]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
2 | * Memory management routine | |
3 | * Copyright (C) 1998 Kunihiro Ishiguro | |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2, or (at your option) any | |
10 | * later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GNU Zebra; see the file COPYING. If not, write to the Free | |
19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | * 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
24 | ||
25 | #include "log.h" | |
26 | #include "memory.h" | |
27 | ||
28 | void alloc_inc (int); | |
29 | void alloc_dec (int); | |
30 | \f | |
31 | struct message mstr [] = | |
32 | { | |
33 | { MTYPE_THREAD, "thread" }, | |
34 | { MTYPE_THREAD_MASTER, "thread_master" }, | |
35 | { MTYPE_VECTOR, "vector" }, | |
36 | { MTYPE_VECTOR_INDEX, "vector_index" }, | |
37 | { MTYPE_IF, "interface" }, | |
38 | { 0, NULL }, | |
39 | }; | |
40 | \f | |
41 | /* Fatal memory allocation error occured. */ | |
42 | static void | |
43 | zerror (const char *fname, int type, size_t size) | |
44 | { | |
45 | fprintf (stderr, "%s : can't allocate memory for `%s' size %d\n", | |
46 | fname, lookup (mstr, type), (int) size); | |
47 | exit (1); | |
48 | } | |
49 | ||
50 | /* Memory allocation. */ | |
51 | void * | |
52 | zmalloc (int type, size_t size) | |
53 | { | |
54 | void *memory; | |
55 | ||
56 | memory = malloc (size); | |
57 | ||
58 | if (memory == NULL) | |
59 | zerror ("malloc", type, size); | |
60 | ||
61 | alloc_inc (type); | |
62 | ||
63 | return memory; | |
64 | } | |
65 | ||
66 | /* Memory allocation with num * size with cleared. */ | |
67 | void * | |
68 | zcalloc (int type, size_t size) | |
69 | { | |
70 | void *memory; | |
71 | ||
72 | memory = calloc (1, size); | |
73 | ||
74 | if (memory == NULL) | |
75 | zerror ("calloc", type, size); | |
76 | ||
77 | alloc_inc (type); | |
78 | ||
79 | return memory; | |
80 | } | |
81 | ||
82 | /* Memory reallocation. */ | |
83 | void * | |
84 | zrealloc (int type, void *ptr, size_t size) | |
85 | { | |
86 | void *memory; | |
87 | ||
88 | memory = realloc (ptr, size); | |
89 | if (memory == NULL) | |
90 | zerror ("realloc", type, size); | |
91 | return memory; | |
92 | } | |
93 | ||
94 | /* Memory free. */ | |
95 | void | |
96 | zfree (int type, void *ptr) | |
97 | { | |
98 | alloc_dec (type); | |
99 | free (ptr); | |
100 | } | |
101 | ||
102 | /* String duplication. */ | |
103 | char * | |
104 | zstrdup (int type, char *str) | |
105 | { | |
106 | void *dup; | |
107 | ||
108 | dup = strdup (str); | |
109 | if (dup == NULL) | |
110 | zerror ("strdup", type, strlen (str)); | |
111 | alloc_inc (type); | |
112 | return dup; | |
113 | } | |
114 | \f | |
115 | #ifdef MEMORY_LOG | |
116 | struct | |
117 | { | |
118 | char *name; | |
119 | unsigned long alloc; | |
120 | unsigned long t_malloc; | |
121 | unsigned long c_malloc; | |
122 | unsigned long t_calloc; | |
123 | unsigned long c_calloc; | |
124 | unsigned long t_realloc; | |
125 | unsigned long t_free; | |
126 | unsigned long c_strdup; | |
127 | } mstat [MTYPE_MAX]; | |
128 | ||
129 | void | |
130 | mtype_log (char *func, void *memory, const char *file, int line, int type) | |
131 | { | |
132 | zlog_info ("%s: %s %p %s %d", func, lookup (mstr, type), memory, file, line); | |
133 | } | |
134 | ||
135 | void * | |
136 | mtype_zmalloc (const char *file, int line, int type, size_t size) | |
137 | { | |
138 | void *memory; | |
139 | ||
140 | mstat[type].c_malloc++; | |
141 | mstat[type].t_malloc++; | |
142 | ||
143 | memory = zmalloc (type, size); | |
144 | mtype_log ("zmalloc", memory, file, line, type); | |
145 | ||
146 | return memory; | |
147 | } | |
148 | ||
149 | void * | |
150 | mtype_zcalloc (const char *file, int line, int type, size_t size) | |
151 | { | |
152 | void *memory; | |
153 | ||
154 | mstat[type].c_calloc++; | |
155 | mstat[type].t_calloc++; | |
156 | ||
157 | memory = zcalloc (type, size); | |
158 | mtype_log ("xcalloc", memory, file, line, type); | |
159 | ||
160 | return memory; | |
161 | } | |
162 | ||
163 | void * | |
164 | mtype_zrealloc (const char *file, int line, int type, void *ptr, size_t size) | |
165 | { | |
166 | void *memory; | |
167 | ||
168 | /* Realloc need before allocated pointer. */ | |
169 | mstat[type].t_realloc++; | |
170 | ||
171 | memory = zrealloc (type, ptr, size); | |
172 | ||
173 | mtype_log ("xrealloc", memory, file, line, type); | |
174 | ||
175 | return memory; | |
176 | } | |
177 | ||
178 | /* Important function. */ | |
179 | void | |
180 | mtype_zfree (const char *file, int line, int type, void *ptr) | |
181 | { | |
182 | mstat[type].t_free++; | |
183 | ||
184 | mtype_log ("xfree", ptr, file, line, type); | |
185 | ||
186 | zfree (type, ptr); | |
187 | } | |
188 | ||
189 | char * | |
190 | mtype_zstrdup (const char *file, int line, int type, char *str) | |
191 | { | |
192 | char *memory; | |
193 | ||
194 | mstat[type].c_strdup++; | |
195 | ||
196 | memory = zstrdup (type, str); | |
197 | ||
198 | mtype_log ("xstrdup", memory, file, line, type); | |
199 | ||
200 | return memory; | |
201 | } | |
202 | #else | |
203 | struct | |
204 | { | |
205 | char *name; | |
206 | unsigned long alloc; | |
207 | } mstat [MTYPE_MAX]; | |
208 | #endif /* MTPYE_LOG */ | |
209 | ||
210 | /* Increment allocation counter. */ | |
211 | void | |
212 | alloc_inc (int type) | |
213 | { | |
214 | mstat[type].alloc++; | |
215 | } | |
216 | ||
217 | /* Decrement allocation counter. */ | |
218 | void | |
219 | alloc_dec (int type) | |
220 | { | |
221 | mstat[type].alloc--; | |
222 | } | |
223 | \f | |
224 | /* Looking up memory status from vty interface. */ | |
225 | #include "vector.h" | |
226 | #include "vty.h" | |
227 | #include "command.h" | |
228 | ||
229 | /* For pretty printng of memory allocate information. */ | |
230 | struct memory_list | |
231 | { | |
232 | int index; | |
233 | char *format; | |
234 | }; | |
235 | ||
236 | struct memory_list memory_list_lib[] = | |
237 | { | |
238 | { MTYPE_TMP, "Temporary memory" }, | |
239 | { MTYPE_ROUTE_TABLE, "Route table " }, | |
240 | { MTYPE_ROUTE_NODE, "Route node " }, | |
241 | { MTYPE_RIB, "RIB " }, | |
242 | { MTYPE_NEXTHOP, "Nexthop " }, | |
243 | { MTYPE_LINK_LIST, "Link List " }, | |
244 | { MTYPE_LINK_NODE, "Link Node " }, | |
245 | { MTYPE_HASH, "Hash " }, | |
246 | { MTYPE_HASH_BACKET, "Hash Bucket " }, | |
247 | { MTYPE_ACCESS_LIST, "Access List " }, | |
248 | { MTYPE_ACCESS_LIST_STR, "Access List Str " }, | |
249 | { MTYPE_ACCESS_FILTER, "Access Filter " }, | |
250 | { MTYPE_PREFIX_LIST, "Prefix List " }, | |
251 | { MTYPE_PREFIX_LIST_STR, "Prefix List Str " }, | |
252 | { MTYPE_PREFIX_LIST_ENTRY, "Prefix List Entry "}, | |
253 | { MTYPE_ROUTE_MAP, "Route map " }, | |
254 | { MTYPE_ROUTE_MAP_NAME, "Route map name " }, | |
255 | { MTYPE_ROUTE_MAP_INDEX, "Route map index " }, | |
256 | { MTYPE_ROUTE_MAP_RULE, "Route map rule " }, | |
257 | { MTYPE_ROUTE_MAP_RULE_STR, "Route map rule str" }, | |
258 | { MTYPE_DESC, "Command desc " }, | |
259 | { MTYPE_BUFFER, "Buffer " }, | |
260 | { MTYPE_BUFFER_DATA, "Buffer data " }, | |
261 | { MTYPE_STREAM, "Stream " }, | |
262 | { MTYPE_KEYCHAIN, "Key chain " }, | |
263 | { MTYPE_KEY, "Key " }, | |
264 | { MTYPE_VTY, "VTY " }, | |
265 | { -1, NULL } | |
266 | }; | |
267 | ||
268 | struct memory_list memory_list_bgp[] = | |
269 | { | |
270 | { MTYPE_BGP_PEER, "BGP peer" }, | |
271 | { MTYPE_ATTR, "BGP attribute" }, | |
272 | { MTYPE_AS_PATH, "BGP aspath" }, | |
273 | { MTYPE_AS_SEG, "BGP aspath seg" }, | |
274 | { MTYPE_AS_STR, "BGP aspath str" }, | |
275 | { 0, NULL }, | |
276 | { MTYPE_BGP_TABLE, "BGP table" }, | |
277 | { MTYPE_BGP_NODE, "BGP node" }, | |
278 | { MTYPE_BGP_ADVERTISE_ATTR, "BGP adv attr" }, | |
279 | { MTYPE_BGP_ADVERTISE, "BGP adv" }, | |
280 | { MTYPE_BGP_ADJ_IN, "BGP adj in" }, | |
281 | { MTYPE_BGP_ADJ_OUT, "BGP adj out" }, | |
282 | { 0, NULL }, | |
283 | { MTYPE_AS_LIST, "BGP AS list" }, | |
284 | { MTYPE_AS_FILTER, "BGP AS filter" }, | |
285 | { MTYPE_AS_FILTER_STR, "BGP AS filter str" }, | |
286 | { 0, NULL }, | |
287 | { MTYPE_COMMUNITY, "community" }, | |
288 | { MTYPE_COMMUNITY_VAL, "community val" }, | |
289 | { MTYPE_COMMUNITY_STR, "community str" }, | |
290 | { 0, NULL }, | |
291 | { MTYPE_ECOMMUNITY, "extcommunity" }, | |
292 | { MTYPE_ECOMMUNITY_VAL, "extcommunity val" }, | |
293 | { MTYPE_ECOMMUNITY_STR, "extcommunity str" }, | |
294 | { 0, NULL }, | |
295 | { MTYPE_COMMUNITY_LIST, "community-list" }, | |
296 | { MTYPE_COMMUNITY_LIST_NAME, "community-list name" }, | |
297 | { MTYPE_COMMUNITY_LIST_ENTRY, "community-list entry" }, | |
298 | { MTYPE_COMMUNITY_LIST_CONFIG, "community-list config" }, | |
299 | { 0, NULL }, | |
300 | { MTYPE_CLUSTER, "Cluster list" }, | |
301 | { MTYPE_CLUSTER_VAL, "Cluster list val" }, | |
302 | { 0, NULL }, | |
303 | { MTYPE_TRANSIT, "BGP transit attr" }, | |
304 | { MTYPE_TRANSIT_VAL, "BGP transit val" }, | |
305 | { 0, NULL }, | |
306 | { MTYPE_BGP_DISTANCE, "BGP distance" }, | |
307 | { MTYPE_BGP_NEXTHOP_CACHE, "BGP nexthop" }, | |
308 | { MTYPE_BGP_CONFED_LIST, "BGP confed list" }, | |
309 | { MTYPE_PEER_UPDATE_SOURCE, "peer update if" }, | |
310 | { MTYPE_BGP_DAMP_INFO, "Dampening info" }, | |
311 | { MTYPE_BGP_REGEXP, "BGP regexp" }, | |
312 | { -1, NULL } | |
313 | }; | |
314 | ||
315 | struct memory_list memory_list_rip[] = | |
316 | { | |
317 | { MTYPE_RIP, "RIP structure " }, | |
318 | { MTYPE_RIP_INFO, "RIP route info " }, | |
319 | { MTYPE_RIP_INTERFACE, "RIP interface " }, | |
320 | { MTYPE_RIP_PEER, "RIP peer " }, | |
321 | { MTYPE_RIP_OFFSET_LIST, "RIP offset list " }, | |
322 | { MTYPE_RIP_DISTANCE, "RIP distance " }, | |
323 | { -1, NULL } | |
324 | }; | |
325 | ||
326 | struct memory_list memory_list_ospf[] = | |
327 | { | |
328 | { MTYPE_OSPF_TOP, "OSPF top " }, | |
329 | { MTYPE_OSPF_AREA, "OSPF area " }, | |
330 | { MTYPE_OSPF_AREA_RANGE, "OSPF area range " }, | |
331 | { MTYPE_OSPF_NETWORK, "OSPF network " }, | |
332 | #ifdef NBMA_ENABLE | |
333 | { MTYPE_OSPF_NEIGHBOR_STATIC,"OSPF static nbr " }, | |
334 | #endif /* NBMA_ENABLE */ | |
335 | { MTYPE_OSPF_IF, "OSPF interface " }, | |
336 | { MTYPE_OSPF_NEIGHBOR, "OSPF neighbor " }, | |
337 | { MTYPE_OSPF_ROUTE, "OSPF route " }, | |
338 | { MTYPE_OSPF_TMP, "OSPF tmp mem " }, | |
339 | { MTYPE_OSPF_LSA, "OSPF LSA " }, | |
340 | { MTYPE_OSPF_LSA_DATA, "OSPF LSA data " }, | |
341 | { MTYPE_OSPF_LSDB, "OSPF LSDB " }, | |
342 | { MTYPE_OSPF_PACKET, "OSPF packet " }, | |
343 | { MTYPE_OSPF_FIFO, "OSPF FIFO queue " }, | |
344 | { MTYPE_OSPF_VERTEX, "OSPF vertex " }, | |
345 | { MTYPE_OSPF_NEXTHOP, "OSPF nexthop " }, | |
346 | { MTYPE_OSPF_PATH, "OSPF path " }, | |
347 | { MTYPE_OSPF_VL_DATA, "OSPF VL data " }, | |
348 | { MTYPE_OSPF_CRYPT_KEY, "OSPF crypt key " }, | |
349 | { MTYPE_OSPF_EXTERNAL_INFO, "OSPF ext. info " }, | |
350 | { MTYPE_OSPF_DISTANCE, "OSPF distance " }, | |
351 | { MTYPE_OSPF_IF_INFO, "OSPF if info " }, | |
352 | { MTYPE_OSPF_IF_PARAMS, "OSPF if params " }, | |
353 | { -1, NULL }, | |
354 | }; | |
355 | ||
356 | struct memory_list memory_list_ospf6[] = | |
357 | { | |
358 | { MTYPE_OSPF6_TOP, "OSPF6 top " }, | |
359 | { MTYPE_OSPF6_AREA, "OSPF6 area " }, | |
360 | { MTYPE_OSPF6_IF, "OSPF6 interface " }, | |
361 | { MTYPE_OSPF6_NEIGHBOR, "OSPF6 neighbor " }, | |
362 | { MTYPE_OSPF6_ROUTE, "OSPF6 route " }, | |
363 | { MTYPE_OSPF6_PREFIX, "OSPF6 prefix " }, | |
364 | { MTYPE_OSPF6_MESSAGE, "OSPF6 message " }, | |
365 | { MTYPE_OSPF6_LSA, "OSPF6 LSA " }, | |
366 | { MTYPE_OSPF6_LSA_SUMMARY, "OSPF6 LSA summary " }, | |
367 | { MTYPE_OSPF6_LSDB, "OSPF6 LSA database" }, | |
368 | { MTYPE_OSPF6_VERTEX, "OSPF6 vertex " }, | |
369 | { MTYPE_OSPF6_SPFTREE, "OSPF6 SPF tree " }, | |
370 | { MTYPE_OSPF6_NEXTHOP, "OSPF6 nexthop " }, | |
371 | { MTYPE_OSPF6_EXTERNAL_INFO,"OSPF6 ext. info " }, | |
372 | { MTYPE_OSPF6_OTHER, "OSPF6 other " }, | |
373 | { -1, NULL }, | |
374 | }; | |
375 | ||
376 | struct memory_list memory_list_separator[] = | |
377 | { | |
378 | { 0, NULL}, | |
379 | {-1, NULL} | |
380 | }; | |
381 | ||
382 | void | |
383 | show_memory_vty (struct vty *vty, struct memory_list *list) | |
384 | { | |
385 | struct memory_list *m; | |
386 | ||
387 | for (m = list; m->index >= 0; m++) | |
388 | if (m->index == 0) | |
389 | vty_out (vty, "-----------------------------\r\n"); | |
390 | else | |
391 | vty_out (vty, "%-22s: %5ld\r\n", m->format, mstat[m->index].alloc); | |
392 | } | |
393 | ||
394 | DEFUN (show_memory_all, | |
395 | show_memory_all_cmd, | |
396 | "show memory all", | |
397 | "Show running system information\n" | |
398 | "Memory statistics\n" | |
399 | "All memory statistics\n") | |
400 | { | |
401 | show_memory_vty (vty, memory_list_lib); | |
402 | show_memory_vty (vty, memory_list_separator); | |
403 | show_memory_vty (vty, memory_list_rip); | |
404 | show_memory_vty (vty, memory_list_separator); | |
405 | show_memory_vty (vty, memory_list_ospf); | |
406 | show_memory_vty (vty, memory_list_separator); | |
407 | show_memory_vty (vty, memory_list_ospf6); | |
408 | show_memory_vty (vty, memory_list_separator); | |
409 | show_memory_vty (vty, memory_list_bgp); | |
410 | ||
411 | return CMD_SUCCESS; | |
412 | } | |
413 | ||
414 | ALIAS (show_memory_all, | |
415 | show_memory_cmd, | |
416 | "show memory", | |
417 | "Show running system information\n" | |
418 | "Memory statistics\n") | |
419 | ||
420 | DEFUN (show_memory_lib, | |
421 | show_memory_lib_cmd, | |
422 | "show memory lib", | |
423 | SHOW_STR | |
424 | "Memory statistics\n" | |
425 | "Library memory\n") | |
426 | { | |
427 | show_memory_vty (vty, memory_list_lib); | |
428 | return CMD_SUCCESS; | |
429 | } | |
430 | ||
431 | DEFUN (show_memory_rip, | |
432 | show_memory_rip_cmd, | |
433 | "show memory rip", | |
434 | SHOW_STR | |
435 | "Memory statistics\n" | |
436 | "RIP memory\n") | |
437 | { | |
438 | show_memory_vty (vty, memory_list_rip); | |
439 | return CMD_SUCCESS; | |
440 | } | |
441 | ||
442 | DEFUN (show_memory_bgp, | |
443 | show_memory_bgp_cmd, | |
444 | "show memory bgp", | |
445 | SHOW_STR | |
446 | "Memory statistics\n" | |
447 | "BGP memory\n") | |
448 | { | |
449 | show_memory_vty (vty, memory_list_bgp); | |
450 | return CMD_SUCCESS; | |
451 | } | |
452 | ||
453 | DEFUN (show_memory_ospf, | |
454 | show_memory_ospf_cmd, | |
455 | "show memory ospf", | |
456 | SHOW_STR | |
457 | "Memory statistics\n" | |
458 | "OSPF memory\n") | |
459 | { | |
460 | show_memory_vty (vty, memory_list_ospf); | |
461 | return CMD_SUCCESS; | |
462 | } | |
463 | ||
464 | DEFUN (show_memory_ospf6, | |
465 | show_memory_ospf6_cmd, | |
466 | "show memory ospf6", | |
467 | SHOW_STR | |
468 | "Memory statistics\n" | |
469 | "OSPF6 memory\n") | |
470 | { | |
471 | show_memory_vty (vty, memory_list_ospf6); | |
472 | return CMD_SUCCESS; | |
473 | } | |
474 | ||
475 | void | |
476 | memory_init () | |
477 | { | |
478 | install_element (VIEW_NODE, &show_memory_cmd); | |
479 | install_element (VIEW_NODE, &show_memory_all_cmd); | |
480 | install_element (VIEW_NODE, &show_memory_lib_cmd); | |
481 | install_element (VIEW_NODE, &show_memory_rip_cmd); | |
482 | install_element (VIEW_NODE, &show_memory_bgp_cmd); | |
483 | install_element (VIEW_NODE, &show_memory_ospf_cmd); | |
484 | install_element (VIEW_NODE, &show_memory_ospf6_cmd); | |
485 | ||
486 | install_element (ENABLE_NODE, &show_memory_cmd); | |
487 | install_element (ENABLE_NODE, &show_memory_all_cmd); | |
488 | install_element (ENABLE_NODE, &show_memory_lib_cmd); | |
489 | install_element (ENABLE_NODE, &show_memory_rip_cmd); | |
490 | install_element (ENABLE_NODE, &show_memory_bgp_cmd); | |
491 | install_element (ENABLE_NODE, &show_memory_ospf_cmd); | |
492 | install_element (ENABLE_NODE, &show_memory_ospf6_cmd); | |
493 | } |