Skip to content

Commit 68caf32

Browse files
committed
isisd: fix memory leak for MT settings static buffers
The multi-topology code in isis_mt.c uses three static buffers to avoid repeated memory allocations during MT settings lookups. These buffers are allocated using XREALLOC in area_mt_settings(), circuit_mt_settings(), and circuit_bcast_mt_set(), growing as needed but never freed during daemon shutdown. This causes the memory leak checker to report three "ISIS MT Area Setting" allocations per router at exit time, as the static buffers persist until process termination without being properly released. The fix moves these function-local static variables to file scope and adds a new mt_fini() cleanup function that frees all three buffers during daemon termination. This function is called from terminate() in isis_main.c alongside the other cleanup functions, ensuring proper memory release when isisd exits. Signed-off-by: Vincent Jardin <vjardin@free.fr>
1 parent 315c079 commit 68caf32

File tree

3 files changed

+38
-22
lines changed

3 files changed

+38
-22
lines changed

isisd/isis_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ static FRR_NORETURN void terminate(int i)
105105
isis_terminate();
106106
isis_sr_term();
107107
isis_srv6_term();
108+
mt_fini();
108109
isis_zebra_stop();
109110

110111
isis_master_terminate();

isisd/isis_mt.c

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ DEFINE_MTYPE_STATIC(ISISD, MT_AREA_SETTING, "ISIS MT Area Setting");
1919
DEFINE_MTYPE_STATIC(ISISD, MT_CIRCUIT_SETTING, "ISIS MT Circuit Setting");
2020
DEFINE_MTYPE_STATIC(ISISD, MT_ADJ_INFO, "ISIS MT Adjacency Info");
2121

22+
/* Static buffers for MT settings - freed by mt_fini() */
23+
static struct isis_area_mt_setting **area_mt_setting_buf;
24+
static unsigned int area_mt_setting_buf_size;
25+
static struct isis_circuit_mt_setting **circuit_mt_setting_buf;
26+
static unsigned int circuit_mt_setting_buf_size;
27+
static uint16_t *circuit_bcast_mt_set_buf;
28+
static unsigned int circuit_bcast_mt_set_buf_size;
29+
2230
bool isis_area_ipv6_dstsrc_enabled(struct isis_area *area)
2331
{
2432
struct isis_area_mt_setting *area_mt_setting;
@@ -213,9 +221,6 @@ bool area_is_mt(struct isis_area *area)
213221
struct isis_area_mt_setting **area_mt_settings(struct isis_area *area,
214222
unsigned int *mt_count)
215223
{
216-
static unsigned int size = 0;
217-
static struct isis_area_mt_setting **rv = NULL;
218-
219224
unsigned int count = 0;
220225
struct listnode *node;
221226
struct isis_area_mt_setting *setting;
@@ -225,16 +230,17 @@ struct isis_area_mt_setting **area_mt_settings(struct isis_area *area,
225230
continue;
226231

227232
count++;
228-
if (count > size) {
229-
rv = XREALLOC(MTYPE_MT_AREA_SETTING, rv,
230-
count * sizeof(*rv));
231-
size = count;
233+
if (count > area_mt_setting_buf_size) {
234+
area_mt_setting_buf = XREALLOC(
235+
MTYPE_MT_AREA_SETTING, area_mt_setting_buf,
236+
count * sizeof(*area_mt_setting_buf));
237+
area_mt_setting_buf_size = count;
232238
}
233-
rv[count - 1] = setting;
239+
area_mt_setting_buf[count - 1] = setting;
234240
}
235241

236242
*mt_count = count;
237-
return rv;
243+
return area_mt_setting_buf;
238244
}
239245

240246
/* Circuit specific MT settings api */
@@ -313,9 +319,6 @@ static int circuit_write_mt_settings(struct isis_circuit *circuit,
313319
struct isis_circuit_mt_setting **
314320
circuit_mt_settings(struct isis_circuit *circuit, unsigned int *mt_count)
315321
{
316-
static unsigned int size = 0;
317-
static struct isis_circuit_mt_setting **rv = NULL;
318-
319322
struct isis_area_mt_setting **area_settings;
320323
unsigned int area_count;
321324

@@ -341,16 +344,17 @@ circuit_mt_settings(struct isis_circuit *circuit, unsigned int *mt_count)
341344
continue;
342345

343346
count++;
344-
if (count > size) {
345-
rv = XREALLOC(MTYPE_MT_AREA_SETTING, rv,
346-
count * sizeof(*rv));
347-
size = count;
347+
if (count > circuit_mt_setting_buf_size) {
348+
circuit_mt_setting_buf = XREALLOC(
349+
MTYPE_MT_AREA_SETTING, circuit_mt_setting_buf,
350+
count * sizeof(*circuit_mt_setting_buf));
351+
circuit_mt_setting_buf_size = count;
348352
}
349-
rv[count - 1] = setting;
353+
circuit_mt_setting_buf[count - 1] = setting;
350354
}
351355

352356
*mt_count = count;
353-
return rv;
357+
return circuit_mt_setting_buf;
354358
}
355359

356360
/* ADJ specific MT API */
@@ -478,8 +482,6 @@ static void mt_set_add(uint16_t **mt_set, unsigned int *size,
478482
static uint16_t *circuit_bcast_mt_set(struct isis_circuit *circuit, int level,
479483
unsigned int *mt_count)
480484
{
481-
static uint16_t *rv;
482-
static unsigned int size;
483485
struct listnode *node;
484486
struct isis_adjacency *adj;
485487

@@ -494,11 +496,13 @@ static uint16_t *circuit_bcast_mt_set(struct isis_circuit *circuit, int level,
494496
if (adj->adj_state != ISIS_ADJ_UP)
495497
continue;
496498
for (unsigned int i = 0; i < adj->mt_count; i++)
497-
mt_set_add(&rv, &size, &count, adj->mt_set[i]);
499+
mt_set_add(&circuit_bcast_mt_set_buf,
500+
&circuit_bcast_mt_set_buf_size, &count,
501+
adj->mt_set[i]);
498502
}
499503

500504
*mt_count = count;
501-
return rv;
505+
return circuit_bcast_mt_set_buf;
502506
}
503507

504508
static void tlvs_add_mt_set(struct isis_area *area, struct isis_tlvs *tlvs,
@@ -557,3 +561,13 @@ void mt_init(void)
557561
circuit_write_mt_settings);
558562
#endif
559563
}
564+
565+
void mt_fini(void)
566+
{
567+
XFREE(MTYPE_MT_AREA_SETTING, area_mt_setting_buf);
568+
area_mt_setting_buf_size = 0;
569+
XFREE(MTYPE_MT_AREA_SETTING, circuit_mt_setting_buf);
570+
circuit_mt_setting_buf_size = 0;
571+
XFREE(MTYPE_MT_AREA_SETTING, circuit_bcast_mt_set_buf);
572+
circuit_bcast_mt_set_buf_size = 0;
573+
}

isisd/isis_mt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,5 @@ void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
110110
void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
111111
uint8_t *id, uint32_t metric);
112112
void mt_init(void);
113+
void mt_fini(void);
113114
#endif

0 commit comments

Comments
 (0)