? lib/aaa-notes.txt Index: lib/ChangeLog =================================================================== RCS file: /var/cvsroot/quagga/lib/ChangeLog,v retrieving revision 1.211 diff -u -p -r1.211 ChangeLog --- lib/ChangeLog 1 Oct 2005 17:38:06 -0000 1.211 +++ lib/ChangeLog 11 Oct 2005 04:18:17 -0000 @@ -1,3 +1,47 @@ +2005-10-11 Paul Jakma + + * memory.c: (general) Add caching of specified types. + Factor of 2 improvement in malloc times for heavily reused + objects. Minor degradation in worst-case usage objects, about + 10% overhead, however those kinds of objects should NOT be + marked cacheable anyway. + Add optional extra useage-stats gathering. + (struct mstat) Add extra fields for caching. Compile time + optional fields for extra statistics. + (alloc_inc) move to top, mark for inlining. Add tide and + mstats supports. + (alloc_dec) ditto. + (zmemory_cache_free) new function, free all cached objects + for a type. + (zmemory_cache_invalidate) new function, invalidate cache, + typically because different size requests have been made + which means caching is no longer safe. + (zmemory_cache_lookup) Quick by-type cache to short-circuit + malloc/free for objects we can easily cache. + (zmemory_cache_add) new function, potentially cache objects + which are freed for reuse. + (zmalloc) Try satisfy request from cache. Add stats support. + (zcalloc) ditto + (zrealloc) invalidate cache - size changes. Add stats support. + (zfree) Stats support, try cache object rather freeing, via + zmemory_cache_add. + (zstrdup) Stats support + (ifdef MEMORY_LOG) remove the stats stuff, done in the core + functions. + (show_memory_vty_header) new function, print an explanatory + header. + (show_memory_vty) Add support for the new stats and cache + fields. + (memory_init) Initialise the mstat array's cacheable field + from memory_lists. + * memory.h: Add cacheable ENUM. Include vty.h, compile warning. + Add cacheable field to struct memory_list. + * memtypes.c: Add cacheable specifiers to all types, based on + observation of which types get good hit rates. + * stream.{c,h}: Seperate the static and variable parts of struct + stream again. We can cache the former quite easily. + + 2005-10-01 Andrew J. Schorr * zebra.h: Declare new functions zebra_route_string() and Index: lib/command.c =================================================================== RCS file: /var/cvsroot/quagga/lib/command.c,v retrieving revision 1.50 diff -u -p -r1.50 command.c --- lib/command.c 5 Sep 2005 11:54:13 -0000 1.50 +++ lib/command.c 11 Oct 2005 04:18:17 -0000 @@ -21,6 +21,9 @@ along with GNU Zebra; see the file COPYI Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#pragma FINI "cmd_terminate" +#pragma fini (cmd_terminate) + #include @@ -167,7 +170,7 @@ argv_concat (const char **argv, int argc len += strlen(argv[i])+1; if (!len) return NULL; - p = str = XMALLOC(MTYPE_TMP, len); + p = str = XMALLOC (MTYPE_TMP, len); for (i = shift; i < argc; i++) { size_t arglen; @@ -342,7 +345,7 @@ cmd_desc_str (const char **string) } /* New string vector. */ -static vector +vector cmd_make_descvec (const char *string, const char *descstr) { int multiple = 0; @@ -362,8 +365,8 @@ cmd_make_descvec (const char *string, co return NULL; allvec = vector_init (VECTOR_MIN_SIZE); - - while (1) + + do { while (isspace ((int) *cp) && *cp != '\0') cp++; @@ -430,7 +433,7 @@ cmd_make_descvec (const char *string, co vector_set (allvec, strvec); } vector_set (strvec, desc); - } + } while (1); } /* Count mandantory string vector size. This is to determine inputed @@ -1890,7 +1893,7 @@ cmd_complete_command_real (vector vline, { char *lcdstr; - lcdstr = XMALLOC (MTYPE_TMP, lcd + 1); + lcdstr = XMALLOC (MTYPE_STRVEC, lcd + 1); memcpy (lcdstr, matchvec->index[0], lcd); lcdstr[lcd] = '\0'; @@ -1900,7 +1903,7 @@ cmd_complete_command_real (vector vline, for (i = 0; i < vector_active (matchvec); i++) { if (vector_slot (matchvec, i)) - XFREE (MTYPE_TMP, vector_slot (matchvec, i)); + XFREE (MTYPE_STRVEC, vector_slot (matchvec, i)); } vector_free (matchvec); @@ -2520,6 +2523,7 @@ DEFUN (config_write_file, { unsigned int i; int fd; + int ret = CMD_WARNING; struct cmd_node *node; char *config_file; char *config_file_tmp = NULL; @@ -2537,12 +2541,12 @@ DEFUN (config_write_file, /* Get filename. */ config_file = host.config; - config_file_sav = malloc (strlen (config_file) + strlen (CONF_BACKUP_EXT) + 1); + config_file_sav = + XMALLOC (MTYPE_TMP, strlen (config_file) + strlen (CONF_BACKUP_EXT) + 1); strcpy (config_file_sav, config_file); strcat (config_file_sav, CONF_BACKUP_EXT); - - - config_file_tmp = malloc (strlen (config_file) + 8); + + config_file_tmp = XMALLOC (MTYPE_TMP, strlen (config_file) + 8); sprintf (config_file_tmp, "%s.XXXXXX", config_file); /* Open file to configuration write. */ @@ -2551,9 +2555,10 @@ DEFUN (config_write_file, { vty_out (vty, "Can't open configuration file %s.%s", config_file_tmp, VTY_NEWLINE); - free (config_file_tmp); - free (config_file_sav); - return CMD_WARNING; + unlink (config_file_tmp); + XFREE (MTYPE_TMP, config_file_tmp); + XFREE (MTYPE_TMP, config_file_sav); + return ret; } /* Make vty for configuration file. */ @@ -2579,55 +2584,45 @@ DEFUN (config_write_file, { vty_out (vty, "Can't unlink backup configuration file %s.%s", config_file_sav, VTY_NEWLINE); - free (config_file_sav); - free (config_file_tmp); - unlink (config_file_tmp); - return CMD_WARNING; + goto finished; } if (link (config_file, config_file_sav) != 0) { vty_out (vty, "Can't backup old configuration file %s.%s", config_file_sav, VTY_NEWLINE); - free (config_file_sav); - free (config_file_tmp); - unlink (config_file_tmp); - return CMD_WARNING; + goto finished; } sync (); if (unlink (config_file) != 0) { vty_out (vty, "Can't unlink configuration file %s.%s", config_file, VTY_NEWLINE); - free (config_file_sav); - free (config_file_tmp); - unlink (config_file_tmp); - return CMD_WARNING; + goto finished; } if (link (config_file_tmp, config_file) != 0) { vty_out (vty, "Can't save configuration file %s.%s", config_file, VTY_NEWLINE); - free (config_file_sav); - free (config_file_tmp); - unlink (config_file_tmp); - return CMD_WARNING; + goto finished; } - unlink (config_file_tmp); sync (); - free (config_file_sav); - free (config_file_tmp); - if (chmod (config_file, CONFIGFILE_MASK) != 0) { vty_out (vty, "Can't chmod configuration file %s: %s (%d).%s", config_file, safe_strerror(errno), errno, VTY_NEWLINE); - return CMD_WARNING; + goto finished; } vty_out (vty, "Configuration saved to %s%s", config_file, VTY_NEWLINE); - return CMD_SUCCESS; + ret = CMD_SUCCESS; + +finished: + unlink (config_file_tmp); + XFREE (MTYPE_TMP, config_file_tmp); + XFREE (MTYPE_TMP, config_file_sav); + return ret; } ALIAS (config_write_file, @@ -2739,9 +2734,9 @@ DEFUN (config_hostname, } if (host.name) - XFREE (0, host.name); + XFREE (MTYPE_HOST, host.name); - host.name = strdup (argv[0]); + host.name = XSTRDUP (MTYPE_HOST, argv[0]); return CMD_SUCCESS; } @@ -2753,7 +2748,7 @@ DEFUN (config_no_hostname, "Host name of this router\n") { if (host.name) - XFREE (0, host.name); + XFREE (MTYPE_HOST, host.name); host.name = NULL; return CMD_SUCCESS; } @@ -2778,11 +2773,11 @@ DEFUN (config_password, password_cmd, if (*argv[0] == '8') { if (host.password) - XFREE (0, host.password); + XFREE (MTYPE_HOST, host.password); host.password = NULL; if (host.password_encrypt) - XFREE (0, host.password_encrypt); - host.password_encrypt = XSTRDUP (0, strdup (argv[1])); + XFREE (MTYPE_HOST, host.password_encrypt); + host.password_encrypt = XSTRDUP (MTYPE_HOST, argv[1]); return CMD_SUCCESS; } else @@ -2800,17 +2795,17 @@ DEFUN (config_password, password_cmd, } if (host.password) - XFREE (0, host.password); + XFREE (MTYPE_HOST, host.password); host.password = NULL; if (host.encrypt) { if (host.password_encrypt) - XFREE (0, host.password_encrypt); - host.password_encrypt = XSTRDUP (0, zencrypt (argv[0])); + XFREE (MTYPE_HOST, host.password_encrypt); + host.password_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (argv[0])); } else - host.password = XSTRDUP (0, argv[0]); + host.password = XSTRDUP (MTYPE_HOST, argv[0]); return CMD_SUCCESS; } @@ -2842,12 +2837,12 @@ DEFUN (config_enable_password, enable_pa if (*argv[0] == '8') { if (host.enable) - XFREE (0, host.enable); + XFREE (MTYPE_HOST, host.enable); host.enable = NULL; if (host.enable_encrypt) - XFREE (0, host.enable_encrypt); - host.enable_encrypt = XSTRDUP (0, argv[1]); + XFREE (MTYPE_HOST, host.enable_encrypt); + host.enable_encrypt = XSTRDUP (MTYPE_HOST, argv[1]); return CMD_SUCCESS; } @@ -2866,18 +2861,18 @@ DEFUN (config_enable_password, enable_pa } if (host.enable) - XFREE (0, host.enable); + XFREE (MTYPE_HOST, host.enable); host.enable = NULL; /* Plain password input. */ if (host.encrypt) { if (host.enable_encrypt) - XFREE (0, host.enable_encrypt); - host.enable_encrypt = XSTRDUP (0, zencrypt (argv[0])); + XFREE (MTYPE_HOST, host.enable_encrypt); + host.enable_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (argv[0])); } else - host.enable = XSTRDUP (0, argv[0]); + host.enable = XSTRDUP (MTYPE_HOST, argv[0]); return CMD_SUCCESS; } @@ -2897,11 +2892,11 @@ DEFUN (no_config_enable_password, no_ena "Assign the privileged level password\n") { if (host.enable) - XFREE (0, host.enable); + XFREE (MTYPE_HOST, host.enable); host.enable = NULL; if (host.enable_encrypt) - XFREE (0, host.enable_encrypt); + XFREE (MTYPE_HOST, host.enable_encrypt); host.enable_encrypt = NULL; return CMD_SUCCESS; @@ -2921,14 +2916,14 @@ DEFUN (service_password_encrypt, if (host.password) { if (host.password_encrypt) - XFREE (0, host.password_encrypt); - host.password_encrypt = XSTRDUP (0, zencrypt (host.password)); + XFREE (MTYPE_HOST, host.password_encrypt); + host.password_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (host.password)); } if (host.enable) { if (host.enable_encrypt) - XFREE (0, host.enable_encrypt); - host.enable_encrypt = XSTRDUP (0, zencrypt (host.enable)); + XFREE (MTYPE_HOST, host.enable_encrypt); + host.enable_encrypt = XSTRDUP (MTYPE_HOST, zencrypt (host.enable)); } return CMD_SUCCESS; @@ -2947,11 +2942,11 @@ DEFUN (no_service_password_encrypt, host.encrypt = 0; if (host.password_encrypt) - XFREE (0, host.password_encrypt); + XFREE (MTYPE_HOST, host.password_encrypt); host.password_encrypt = NULL; if (host.enable_encrypt) - XFREE (0, host.enable_encrypt); + XFREE (MTYPE_HOST, host.enable_encrypt); host.enable_encrypt = NULL; return CMD_SUCCESS; @@ -3029,7 +3024,7 @@ DEFUN_HIDDEN (do_echo, vty_out (vty, "%s%s", ((message = argv_concat(argv, argc, 0)) ? message : ""), VTY_NEWLINE); if (message) - XFREE(MTYPE_TMP, message); + XFREE (MTYPE_TMP, message); return CMD_SUCCESS; } @@ -3048,7 +3043,7 @@ DEFUN (config_logmsg, zlog(NULL, level, ((message = argv_concat(argv, argc, 1)) ? message : "")); if (message) - XFREE(MTYPE_TMP, message); + XFREE (MTYPE_TMP, message); return CMD_SUCCESS; } @@ -3220,9 +3215,9 @@ set_log_file(struct vty *vty, const char } if (host.logfile) - XFREE (MTYPE_TMP, host.logfile); + XFREE (MTYPE_HOST, host.logfile); - host.logfile = XSTRDUP (MTYPE_TMP, fname); + host.logfile = XSTRDUP (MTYPE_HOST, fname); return CMD_SUCCESS; } @@ -3263,7 +3258,7 @@ DEFUN (no_config_log_file, zlog_reset_file (NULL); if (host.logfile) - XFREE (MTYPE_TMP, host.logfile); + XFREE (MTYPE_HOST, host.logfile); host.logfile = NULL; @@ -3432,8 +3427,8 @@ DEFUN (banner_motd_file, "Filename\n") { if (host.motdfile) - XFREE (MTYPE_TMP, host.motdfile); - host.motdfile = XSTRDUP (MTYPE_TMP, argv[0]); + XFREE (MTYPE_HOST, host.motdfile); + host.motdfile = XSTRDUP (MTYPE_HOST, argv[0]); return CMD_SUCCESS; } @@ -3458,7 +3453,7 @@ DEFUN (no_banner_motd, { host.motd = NULL; if (host.motdfile) - XFREE (MTYPE_TMP, host.motdfile); + XFREE (MTYPE_HOST, host.motdfile); host.motdfile = NULL; return CMD_SUCCESS; } @@ -3467,7 +3462,7 @@ DEFUN (no_banner_motd, void host_config_set (char *filename) { - host.config = strdup (filename); + host.config = XSTRDUP (MTYPE_HOST, filename); } void @@ -3486,6 +3481,74 @@ install_default (enum node_type node) install_element (node, &show_running_config_cmd); } +void +cmd_descvec_free (vector descvec) +{ + unsigned int i; + struct desc *desc; + + for (i = 0; i < vector_active (descvec); i++) + if ( (desc = vector_slot (descvec, i)) != NULL) + { + XFREE (MTYPE_TMP, desc->cmd); + XFREE (MTYPE_STRVEC, desc->str); + desc->cmd = NULL; + desc->str = NULL; + XFREE (MTYPE_DESC, desc); + desc = NULL; + } + vector_free (descvec); + descvec = NULL; +} + +void +cmd_element_terminate (struct cmd_element *cmd_element) +{ + unsigned int i; + + if (!cmd_element->strvec) + return; + + for (i = 0; i < vector_active (cmd_element->strvec); i++) + if (vector_slot (cmd_element->strvec, i) != NULL) + cmd_descvec_free (vector_slot (cmd_element->strvec, i)); + + vector_free (cmd_element->strvec); + cmd_element->strvec = NULL; +} + +void +cmd_node_terminate (struct cmd_node *cnode) +{ + unsigned int i; + + if (!cnode->cmd_vector) + return; + + for (i = 0; i < vector_active (cnode->cmd_vector); i++) + if (vector_slot (cnode->cmd_vector, i) != NULL) + cmd_element_terminate (vector_slot (cnode->cmd_vector, i)); + + vector_free (cnode->cmd_vector); + cnode->cmd_vector = NULL; +} + +/* Free all cmdnode's and cmd_elements in the master cmdvec */ +__attribute__ ((destructor)) +void +cmd_terminate (void) +{ + unsigned int i; + + if (!cmdvec) + return; + + for (i = 0; i < vector_active (cmdvec); i++) + if (vector_slot (cmdvec, i) != NULL) + cmd_node_terminate (vector_slot (cmdvec, i)); + vector_free (cmdvec); +} + /* Initialize command interface. Install basic nodes and commands. */ void cmd_init (int terminal) Index: lib/if.c =================================================================== RCS file: /var/cvsroot/quagga/lib/if.c,v retrieving revision 1.31 diff -u -p -r1.31 if.c --- lib/if.c 6 May 2005 21:25:49 -0000 1.31 +++ lib/if.c 11 Oct 2005 04:18:19 -0000 @@ -495,7 +495,7 @@ DEFUN (no_interface_desc, ifp = vty->index; if (ifp->desc) - XFREE (0, ifp->desc); + XFREE (MTYPE_TMP, ifp->desc); ifp->desc = NULL; return CMD_SUCCESS; Index: lib/if_rmap.c =================================================================== RCS file: /var/cvsroot/quagga/lib/if_rmap.c,v retrieving revision 1.7 diff -u -p -r1.7 if_rmap.c --- lib/if_rmap.c 6 May 2005 21:25:49 -0000 1.7 +++ lib/if_rmap.c 11 Oct 2005 04:18:19 -0000 @@ -47,12 +47,12 @@ static void if_rmap_free (struct if_rmap *if_rmap) { if (if_rmap->ifname) - free (if_rmap->ifname); + XFREE (MTYPE_IF_RMAP_NAME, if_rmap->ifname); if (if_rmap->routemap[IF_RMAP_IN]) - free (if_rmap->routemap[IF_RMAP_IN]); + XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]); if (if_rmap->routemap[IF_RMAP_OUT]) - free (if_rmap->routemap[IF_RMAP_OUT]); + XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]); XFREE (MTYPE_IF_RMAP, if_rmap); } @@ -90,7 +90,7 @@ if_rmap_hash_alloc (void *arg) struct if_rmap *if_rmap; if_rmap = if_rmap_new (); - if_rmap->ifname = strdup (ifarg->ifname); + if_rmap->ifname = XSTRDUP (MTYPE_IF_RMAP_NAME, ifarg->ifname); return if_rmap; } @@ -140,14 +140,16 @@ if_rmap_set (const char *ifname, enum if if (type == IF_RMAP_IN) { if (if_rmap->routemap[IF_RMAP_IN]) - free (if_rmap->routemap[IF_RMAP_IN]); - if_rmap->routemap[IF_RMAP_IN] = strdup (routemap_name); + XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]); + if_rmap->routemap[IF_RMAP_IN] + = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name); } if (type == IF_RMAP_OUT) { if (if_rmap->routemap[IF_RMAP_OUT]) - free (if_rmap->routemap[IF_RMAP_OUT]); - if_rmap->routemap[IF_RMAP_OUT] = strdup (routemap_name); + XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]); + if_rmap->routemap[IF_RMAP_OUT] + = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name); } if (if_rmap_add_hook) @@ -173,7 +175,7 @@ if_rmap_unset (const char *ifname, enum if (strcmp (if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0) return 0; - free (if_rmap->routemap[IF_RMAP_IN]); + XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]); if_rmap->routemap[IF_RMAP_IN] = NULL; } @@ -184,7 +186,7 @@ if_rmap_unset (const char *ifname, enum if (strcmp (if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0) return 0; - free (if_rmap->routemap[IF_RMAP_OUT]); + XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]); if_rmap->routemap[IF_RMAP_OUT] = NULL; } Index: lib/md5.c =================================================================== RCS file: /var/cvsroot/quagga/lib/md5.c,v retrieving revision 1.3 diff -u -p -r1.3 md5.c --- lib/md5.c 28 Sep 2005 15:47:44 -0000 1.3 +++ lib/md5.c 11 Oct 2005 04:18:19 -0000 @@ -137,10 +137,9 @@ static const u_int8_t md5_paddat[MD5_BUF 0, 0, 0, 0, 0, 0, 0, 0, }; -static void md5_calc __P((u_int8_t *, md5_ctxt *)); +static void md5_calc __P((const u_int8_t *, md5_ctxt *)); -void md5_init(ctxt) - md5_ctxt *ctxt; +void md5_init(md5_ctxt *ctxt) { ctxt->md5_n = 0; ctxt->md5_i = 0; @@ -151,10 +150,7 @@ void md5_init(ctxt) bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf)); } -void md5_loop(ctxt, input, len) - md5_ctxt *ctxt; - u_int8_t *input; - u_int len; /* number of bytes */ +void md5_loop(md5_ctxt *ctxt, const u_int8_t *input, u_int len) { u_int gap, i; @@ -162,42 +158,36 @@ void md5_loop(ctxt, input, len) gap = MD5_BUFLEN - ctxt->md5_i; if (len >= gap) { - bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i), - gap); + memcpy (ctxt->md5_buf + ctxt->md5_i, input, gap); md5_calc(ctxt->md5_buf, ctxt); for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) { - md5_calc((u_int8_t *)(input + i), ctxt); + md5_calc((input + i), ctxt); } ctxt->md5_i = len - i; - bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i); + memcpy (ctxt->md5_buf, (input + i), ctxt->md5_i); } else { - bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i), - len); + memcpy (ctxt->md5_buf + ctxt->md5_i, input, len); ctxt->md5_i += len; } } -void md5_pad(ctxt) - md5_ctxt *ctxt; +void md5_pad(md5_ctxt *ctxt) { u_int gap; /* Don't count up padding. Keep md5_n. */ gap = MD5_BUFLEN - ctxt->md5_i; if (gap > 8) { - bcopy((void *)md5_paddat, - (void *)(ctxt->md5_buf + ctxt->md5_i), - gap - sizeof(ctxt->md5_n)); + memcpy (ctxt->md5_buf + ctxt->md5_i, md5_paddat, + gap - sizeof(ctxt->md5_n)); } else { /* including gap == 8 */ - bcopy((void *)md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i), - gap); - md5_calc(ctxt->md5_buf, ctxt); - bcopy((void *)(md5_paddat + gap), - (void *)ctxt->md5_buf, - MD5_BUFLEN - sizeof(ctxt->md5_n)); + memcpy (ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap); + md5_calc (ctxt->md5_buf, ctxt); + memcpy (ctxt->md5_buf, md5_paddat + gap, + MD5_BUFLEN - sizeof(ctxt->md5_n)); } /* 8 byte word */ @@ -218,13 +208,11 @@ void md5_pad(ctxt) md5_calc(ctxt->md5_buf, ctxt); } -void md5_result(digest, ctxt) - u_int8_t *digest; - md5_ctxt *ctxt; +void md5_result(u_int8_t *digest, md5_ctxt *ctxt) { /* 4 byte words */ #if BYTE_ORDER == LITTLE_ENDIAN - bcopy(&ctxt->md5_st8[0], digest, 16); + memcpy (digest, &ctxt->md5_st8[0], 16); #endif #if BYTE_ORDER == BIG_ENDIAN digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2]; @@ -242,16 +230,14 @@ void md5_result(digest, ctxt) u_int32_t X[16]; #endif -static void md5_calc(b64, ctxt) - u_int8_t *b64; - md5_ctxt *ctxt; +static void md5_calc(const u_int8_t *b64, md5_ctxt * ctxt) { u_int32_t A = ctxt->md5_sta; u_int32_t B = ctxt->md5_stb; u_int32_t C = ctxt->md5_stc; u_int32_t D = ctxt->md5_std; #if BYTE_ORDER == LITTLE_ENDIAN - u_int32_t *X = (u_int32_t *)b64; + const u_int32_t *X = (const u_int32_t *)b64; #endif #if BYTE_ORDER == BIG_ENDIAN /* 4 byte words */ Index: lib/md5.h =================================================================== RCS file: /var/cvsroot/quagga/lib/md5.h,v retrieving revision 1.1 diff -u -p -r1.1 md5.h --- lib/md5.h 28 Sep 2005 15:47:44 -0000 1.1 +++ lib/md5.h 11 Oct 2005 04:18:19 -0000 @@ -68,7 +68,7 @@ typedef struct { } md5_ctxt; extern void md5_init __P((md5_ctxt *)); -extern void md5_loop __P((md5_ctxt *, u_int8_t *, u_int)); +extern void md5_loop __P((md5_ctxt *, const u_int8_t *, u_int)); extern void md5_pad __P((md5_ctxt *)); extern void md5_result __P((u_int8_t *, md5_ctxt *)); Index: lib/memory.c =================================================================== RCS file: /var/cvsroot/quagga/lib/memory.c,v retrieving revision 1.14 diff -u -p -r1.14 memory.c --- lib/memory.c 6 May 2005 21:25:49 -0000 1.14 +++ lib/memory.c 11 Oct 2005 04:18:19 -0000 @@ -25,10 +25,21 @@ #include "log.h" #include "memory.h" -static void alloc_inc (int); -static void alloc_dec (int); -static void log_memstats(int log_priority); +/* some debug and probably performance debilitating compile options.. */ +#define MTYPE_EXTRA_STATS 1 +/* Tide optimisation (if it actually is an optimisation */ +#define MTYPE_TRACK_TIDES 0 +/* free() debugging: poison on free if possible and verify poison on realloc, + * check for double-free's. + * This will use a lot of extra RAM. + */ +#define MTYPE_POISON 1 +/* Redzone tracking (where possible - size must stay same for object) */ +#define MTYPE_REDZONE 1 +static void log_memstats(int log_priority); +static const int redzone_marker = 0xf0f0f0f0; + static struct message mstr [] = { { MTYPE_THREAD, "thread" }, @@ -54,19 +65,369 @@ zerror (const char *fname, int type, siz abort(); } +/* most objects for a type we can try cache */ +/* If poisoning, cache lots of them so we get to verify lots of poison fill */ +#if defined(MTYPE_POISON) && (MTYPE_POISON > 0) +#define MTYPE_CACHE_NUM_SLOTS 50 +#else +/* Normally we only want a very few cache slots, as these are statically + * allocated + */ +#define MTYPE_CACHE_NUM_SLOTS 3 +#endif /* MTYPE_POISON */ + +/* Allocations / frees can be thought of as coming in 'tides', with a 'flow' + * of allocations followed by an 'ebb' of frees. We're really only interested + * in caching tides whose length is not much greater than the number of + * cache slots (ie, allocation patterns we can get a reasonably good hit + * rate on). Caching (ie not freeing) the first $FEW frees of a very long + * "tidal pattern" isn't going to do much, and at worst would just stuff + * things up for the underlying libc allocator (eg, fragmentation). + * + * Hence we track: + * flow: the current length and direction of flow or ebb + * + * And we only cache allocations while the ebb or flow is <= an + * arbitrary bound on the tide. Ie, we only cache objects whose + * allocation pattern has recently tended to be a roughly symmetrical + * series of allocs/frees, allowed to skew only within this bound. + */ +#define MTYPE_CACHE_TIDE (MTYPE_CACHE_NUM_SLOTS * 16) + +/* absolute value of the signed flow value */ +#define MTYPE_CACHE_FLOW_ABS(T) \ + ((mstat[(T)].flow >= 0) ? (mstat[(T)].flow) \ + : (-mstat[(T)].flow)) + +/* Is cache valid? */ +#define CACHE_IS_INVALID(T) (mstat[(T)].cache_used == -1) + +static struct +{ + unsigned long alloc; + size_t cached_size; /* size of objects cached */ +#if (MTYPE_TRACK_TIDES > 0) + int flow; /* the current direction and length of the tide */ +#endif + void *cache_slot[MTYPE_CACHE_NUM_SLOTS]; + int cache_used; /* -1 means never ever cache again, see zrealloc() */ + enum mtype_cacheable cacheable; +#if (MTYPE_EXTRA_STATS > 0) + unsigned long st_cache_hit; + unsigned long st_cache_invalidated; + unsigned long st_cache_revalidated; + unsigned long st_cache_add; + unsigned long st_malloc; + unsigned long st_calloc; + unsigned long st_realloc; + unsigned long st_strdup; + unsigned long st_free; +#endif /* MTYPE_EXTRA_STATS */ +} mstat [MTYPE_MAX]; + +/* Increment allocation counter. */ +static inline void +alloc_inc (int type) +{ + mstat[type].alloc++; + +#if (MTYPE_TRACK_TIDES > 0) + if (mstat[type].flow < 0) + mstat[type].flow = 1; + else + mstat[type].flow++; +#endif /* MTYPE_TRACK_TIDES */ +} + +/* Decrement allocation counter. */ +static inline void +alloc_dec (int type) +{ + mstat[type].alloc--; + +#if (MTYPE_TRACK_TIDES > 0) + if (mstat[type].flow > 0) + mstat[type].flow = -1; + else + mstat[type].flow--; +#endif /* MTYPE_TRACK_TIDES */ +} + +/* free the cache, eg because it was invalidated, or the tide is too + * long + */ +static void +zmemory_cache_free (int type) +{ + while (mstat[type].cache_used > 0) + { + mstat[type].cache_used--; + free (mstat[type].cache_slot[mstat[type].cache_used]); + } +} + +/* invalidate the cache. Free all entries. Reset cached_size */ +static void +zmemory_cache_invalidate (int type) +{ + mstat[type].cached_size = 0; + +#if (MTYPE_EXTRA_STATS > 0) + mstat[type].st_cache_invalidated++; +#endif /* MTYPE_EXTRA_STATS */ + + zmemory_cache_free (type); + + mstat[type].cache_used = -1; +} + +/* helper to fill pointed to buffer + * only for use by zpoison and zpoison_verify + */ +static void +zpoison_fill (unsigned int *p, size_t size, unsigned int fill) +{ + unsigned int i; + + for (i = 0; i < (size / sizeof (fill)); i++) + memcpy ((p + i), &fill, sizeof (fill)); + + if (size % sizeof (fill)) + memcpy ((p + i), &fill, size % sizeof (fill)); +} + +static const unsigned int poison = 0x00000badU; +static const unsigned int antidote = 0xdeadbeefU; + +/* poison memory */ +static void +zpoison (int type, void *ptr) +{ + /* only if cache is valid can we have a size */ + if (CACHE_IS_INVALID (type)) + return; + + /* if cache is valid, and we're poisoning freed object, we surely must + * have a size cached.. + */ + assert (mstat[type].cached_size > 0); + + zpoison_fill (ptr, mstat[type].cached_size, poison); + + return; +} + +static inline void * +zpoison_verify (int type, unsigned int *ptr) +{ + unsigned int i; + + assert (!CACHE_IS_INVALID (type) && mstat[type].cached_size > 0); + + for (i = 0; i < (mstat[type].cached_size / sizeof (poison)); i++) + assert (*(ptr + i) == poison); + + zpoison_fill (ptr, mstat[type].cached_size, antidote); + + return ptr; +} + +/* Lookup cache entry for (type,size) This is a simple, low overhead + * cache to mitigate costs of repeated malloc(x)/free by higher level + * code which existing malloc implementations dont seem to deal well + * with. + * + * As we have a memory type parameter, information not available to a libc, + * and we already maintain stats per mtype, we can implement a low-overhead + * cache to short-circuit repetitive malloc(x)/free from having to go into + * system malloc()/free(). + * + * We cant handle the size changing, if we detect different size requests + * of memory for a type, the cache for that type is cleared and invalidated + * and will remain invalid until allocations for the type return to 0. + * + * Note that the most important function here is to: + * - detect size changing + * - keep cache invalid while different size allocations are outstanding + * + * For we use the size parameter to do things other than just cache types + * (overflow redzones) + */ +static void * +zmemory_cache_lookup (int type, size_t size) +{ + /* Caching invalid for this type, if all objects have been returned, + * we can enable caching again + */ + if (CACHE_IS_INVALID (type)) + { + /* If all outstanding allocations are returned, cache be can made + * valid again, otherwise left it is left as invalid. + * + * the still-invalid case is put first as all x86 CPUs seem to + * consider the first outcome of a branch as the most likely for + * branch prediction purposes.. + */ + if (mstat[type].alloc > 0) + return NULL; + else + { +#if (MTYPE_EXTRA_STATS > 0) + mstat[type].st_cache_revalidated++; +#endif /* MTYPE_EXTRA_STATS */ + + mstat[type].cache_used = 0; + } + } + + /* cache must be valid at this point. + * Three possibilities: + * - it's the first alloc (possibly after revalidation): + * size will be zero, record the size. + * - the size is the same: + * see if we can satisfy from cache + * - the size is different: + * invalidate the cache + */ + + /* record size for now */ + if (mstat[type].cached_size == 0) + { + mstat[type].cached_size = size; + return NULL; + } + + /* cache_used && cached_size must both be >= here */ + if (size == mstat[type].cached_size) + { + /* Not a cacheable type, or nothing cached, + * but we've done our job of tracking size + */ + if (mstat[type].cacheable != MTYPE_CACHE + || mstat[type].cache_used == 0) + return NULL; + +#if (MTYPE_EXTRA_STATS > 0) + mstat[type].st_cache_hit++; +#endif /* MTYPE_EXTRA_STATS */ + + mstat[type].cache_used--; + +#define MTYPE_CACHED_SLOT(T) (mstat[(T)].cache_slot[mstat[(T)].cache_used]) + if (MTYPE_POISON) + return zpoison_verify (type, MTYPE_CACHED_SLOT (type)); + else + return MTYPE_CACHED_SLOT (type); + } + else + { + /* size doesnt match, invalidate cache which will + * mark cache as unusable for now + */ + zmemory_cache_invalidate (type); + } + return NULL; +} + +/* return 0 or 1 to signify whether memory was cached. + * 0 - not added to cache + * 1 - added to cache + * + * caller is left to free (or not) as appropriate. + */ +static inline int +zmemory_cache_add (int type, void *p) +{ + int i; + /* caching invalid for this type */ + if (mstat[type].cacheable != MTYPE_CACHE + || CACHE_IS_INVALID (type)) + return 0; + + /* Double free check */ + if (MTYPE_POISON) + for (i = 0; i < mstat[type].cache_used; i++) + assert (mstat[type].cache_slot[i] != p); + +#if (MTYPE_TRACK_TIDES > 0) + /* Tide check: last tide and the current flow of the tide should be + * less than MTYPE_CACHE_TIDE. An object with very long 'tides' isn't + * worth caching. + */ + if (MTYPE_CACHE_FLOW_ABS(type) > MTYPE_CACHE_TIDE) + { + zmemory_cache_free (type); + return 0; + } +#endif /* MTYPE_TRACK_TIDES */ + + if (mstat[type].cache_used < MTYPE_CACHE_NUM_SLOTS) + { +#if (MTYPE_EXTRA_STATS > 0) + mstat[type].st_cache_add++; +#endif /* MTYPE_EXTRA_STATS */ + + mstat[type].cache_slot[mstat[type].cache_used] = p; + mstat[type].cache_used++; + return 1; + } + + return 0; +} + +/* Round up given size to where redzone would start, naturally aligned */ +#define REDZONE_ROUNDUP(S) \ + (1 + (((S) - 1) | (sizeof (redzone_marker) - 1))) +#define MTYPE_SIZE_WITH_REDZONE(S) \ + (REDZONE_ROUNDUP(S) + sizeof (redzone_marker)) + +static void +zredzone_add (char *p, size_t size) +{ + *((int *)(p + REDZONE_ROUNDUP(size))) = redzone_marker; +} + +static void +zredzone_verify (int type, char *p) +{ + size_t size = mstat[type].cached_size; + + if (CACHE_IS_INVALID (type)) + return; + + if (size > 0) + assert (*((int *)(p + REDZONE_ROUNDUP(size))) == redzone_marker); + else + assert (mstat[type].alloc == 0); +} + /* Memory allocation. */ void * zmalloc (int type, size_t size) { void *memory; - - memory = malloc (size); + + /* try the cache */ + if ( (memory = zmemory_cache_lookup (type, size)) == NULL) + { + if (MTYPE_REDZONE) + memory = malloc (REDZONE_ROUNDUP(size) + sizeof (redzone_marker)); + else + memory = malloc (size); + } if (memory == NULL) zerror ("malloc", type, size); - + + if (MTYPE_REDZONE) + zredzone_add (memory, size); + alloc_inc (type); - + +#if (MTYPE_EXTRA_STATS > 0) + mstat[type].st_malloc++; +#endif /* MTYPE_EXTRA_STATS */ + return memory; } @@ -76,11 +437,26 @@ zcalloc (int type, size_t size) { void *memory; - memory = calloc (1, size); + if ( (memory = zmemory_cache_lookup (type, size)) != NULL) + memset (memory, 0, size); + else + { + if (MTYPE_REDZONE) + memory = calloc (1, REDZONE_ROUNDUP(size) + sizeof (redzone_marker)); + else + memory = calloc (1, size); + } if (memory == NULL) zerror ("calloc", type, size); + if (MTYPE_REDZONE) + zredzone_add (memory, size); + +#if (MTYPE_EXTRA_STATS > 0) + mstat[type].st_calloc++; +#endif /* MTYPE_EXTRA_STATS */ + alloc_inc (type); return memory; @@ -91,10 +467,25 @@ void * zrealloc (int type, void *ptr, size_t size) { void *memory; - + + if (ptr == NULL) + return zmalloc (type, size); + + if (MTYPE_REDZONE) + zredzone_verify (type, ptr); + + /* invalidate cache if not already invalid */ + if (mstat[type].cache_used >= 0) + zmemory_cache_invalidate (type); + memory = realloc (ptr, size); if (memory == NULL) zerror ("realloc", type, size); + +#if (MTYPE_EXTRA_STATS > 0) + mstat[type].st_realloc++; +#endif /* MTYPE_EXTRA_STATS */ + return memory; } @@ -102,8 +493,21 @@ zrealloc (int type, void *ptr, size_t si void zfree (int type, void *ptr) { + if (MTYPE_POISON) + zpoison (type, ptr); + + if (MTYPE_REDZONE) + zredzone_verify (type, ptr); + + /* try add to cache, free if it wasnt cached */ + if (zmemory_cache_add (type, ptr) == 0) + free(ptr); + +#if (MTYPE_EXTRA_STATS > 0) + mstat[type].st_free++; +#endif /* MTYPE_EXTRA_STATS */ + alloc_dec (type); - free (ptr); } /* String duplication. */ @@ -111,28 +515,25 @@ char * zstrdup (int type, const char *str) { void *dup; - + dup = strdup (str); if (dup == NULL) zerror ("strdup", type, strlen (str)); + + /* invalidate cache if not already invalid, we have no idea of size */ + if (mstat[type].cache_used >= 0) + zmemory_cache_invalidate (type); + +#if (MTYPE_EXTRA_STATS > 0) + mstat[type].st_strdup++; +#endif /* MTYPE_EXTRA_STATS */ + alloc_inc (type); + return dup; } #ifdef MEMORY_LOG -static struct -{ - const char *name; - unsigned long alloc; - unsigned long t_malloc; - unsigned long c_malloc; - unsigned long t_calloc; - unsigned long c_calloc; - unsigned long t_realloc; - unsigned long t_free; - unsigned long c_strdup; -} mstat [MTYPE_MAX]; - static void mtype_log (char *func, void *memory, const char *file, int line, int type) { @@ -144,9 +545,6 @@ mtype_zmalloc (const char *file, int lin { void *memory; - mstat[type].c_malloc++; - mstat[type].t_malloc++; - memory = zmalloc (type, size); mtype_log ("zmalloc", memory, file, line, type); @@ -158,9 +556,6 @@ mtype_zcalloc (const char *file, int lin { void *memory; - mstat[type].c_calloc++; - mstat[type].t_calloc++; - memory = zcalloc (type, size); mtype_log ("xcalloc", memory, file, line, type); @@ -172,9 +567,6 @@ mtype_zrealloc (const char *file, int li { void *memory; - /* Realloc need before allocated pointer. */ - mstat[type].t_realloc++; - memory = zrealloc (type, ptr, size); mtype_log ("xrealloc", memory, file, line, type); @@ -186,10 +578,7 @@ mtype_zrealloc (const char *file, int li void mtype_zfree (const char *file, int line, int type, void *ptr) { - mstat[type].t_free++; - mtype_log ("xfree", ptr, file, line, type); - zfree (type, ptr); } @@ -198,35 +587,13 @@ mtype_zstrdup (const char *file, int lin { char *memory; - mstat[type].c_strdup++; - memory = zstrdup (type, str); mtype_log ("xstrdup", memory, file, line, type); return memory; } -#else -static struct -{ - char *name; - unsigned long alloc; -} mstat [MTYPE_MAX]; #endif /* MTPYE_LOG */ - -/* Increment allocation counter. */ -static void -alloc_inc (int type) -{ - mstat[type].alloc++; -} - -/* Decrement allocation counter. */ -static void -alloc_dec (int type) -{ - mstat[type].alloc--; -} /* Looking up memory status from vty interface. */ #include "vector.h" @@ -256,15 +623,115 @@ static struct memory_list memory_list_se }; static void +show_memory_vty_header (struct vty *vty) +{ + vty_out (vty, "%12s\t%s%s", "Cached:", + "Objects cached, -1 for invalidated cache", + VTY_NEWLINE); + vty_out (vty, "%12s\t%s%s", "Size Cached:", + "Size of objects in bytes", VTY_NEWLINE); +#if (MTYPE_TRACK_TIDES > 0) + vty_out (vty, "%12s\t%s%s", "flow:", + "Length of current flow/ebb (negative for ebb/free's)", + VTY_NEWLINE); +#endif +#if (MTYPE_EXTRA_STATS > 0) + vty_out (vty, "%12s\t%s%s", "cache hit:", + "Request satisfied from cache", + VTY_NEWLINE); + vty_out (vty, "%12s\t%s%s", "cache add:", + "Times object added to cache rather than freed", + VTY_NEWLINE); + vty_out (vty, "%12s\t%s%s", "inval:", + "Cache invalidated due to request size mismatch", + VTY_NEWLINE); + vty_out (vty, "%12s\t%s%s", "reval:", + "Invalid cache revalidated and useable again", + VTY_NEWLINE); + vty_out (vty, "%12s\t%s%s", "diff:", + "Discrepancy between allocations - free and 'allocated'", + VTY_NEWLINE); +#endif /* MTYPE_EXTRA_STATS */ + + vty_out (vty, "Cache slots: %3d, Poisoning: %senabled, " + "Redzone: %senabled%s", + MTYPE_CACHE_NUM_SLOTS, + (MTYPE_POISON > 0) ? "" : "not ", + (MTYPE_REDZONE > 0) ? "" : "not ", + VTY_NEWLINE); + + vty_out (vty, "%s%-28s | %10s | %10s | %11s | %7s%s", + VTY_NEWLINE, + "Memory Type", "Allocated", "Cached", "Size Cached", + "Caching", VTY_NEWLINE); +} + +static void show_memory_vty (struct vty *vty, struct memory_list *list) { struct memory_list *m; + show_memory_vty_header (vty); + for (m = list; m->index >= 0; m++) if (m->index == 0) - vty_out (vty, "-----------------------------\r\n"); + vty_out (vty, "-----------------------------%s", VTY_NEWLINE); else - vty_out (vty, "%-30s: %10ld\r\n", m->format, mstat[m->index].alloc); + { + vty_out (vty, "%-28s | %10lu | %10d | %11lu | %7s%s", + m->format, + mstat[m->index].alloc, + mstat[m->index].cache_used, + mstat[m->index].cached_size, + (mstat[m->index].cacheable == MTYPE_CACHE + && !CACHE_IS_INVALID(m->index)) ? "yes" : "no", + VTY_NEWLINE); +#if (MTYPE_EXTRA_STATS > 0) + { + long int diff = mstat[m->index].alloc + - (mstat[m->index].st_strdup + + mstat[m->index].st_calloc + + mstat[m->index].st_malloc + - mstat[m->index].st_free); + + vty_out (vty, "%28s | %10lu | %10lu | %11lu |%s", + "malloc | calloc | realloc", + mstat[m->index].st_malloc, + mstat[m->index].st_calloc, + mstat[m->index].st_realloc, + VTY_NEWLINE); + vty_out (vty, "%-28s | %10lu | %10lu | %11ld |%s", + " strdup | free | diff", + mstat[m->index].st_strdup, + mstat[m->index].st_free, + diff, + VTY_NEWLINE); + vty_out (vty, "%-28s | %10lu | %10lu |%s", + "cache hit | add |", + mstat[m->index].st_cache_hit, + mstat[m->index].st_cache_add, + VTY_NEWLINE); + vty_out (vty, "%-28s | %10lu | %10lu |%s", + " inval | reval |", + mstat[m->index].st_cache_invalidated, + mstat[m->index].st_cache_revalidated, + VTY_NEWLINE); + } +#endif /* MTYPE_EXTRA_STATS */ + +#if (MTYPE_TRACK_TIDES > 0) + vty_out (vty, "%-28s | %10d |%s", + " flow |", + mstat[m->index].flow, + VTY_NEWLINE); +#endif /* MTYPE_TRACK_TIDES */ + + /* If we don't have the extra stats output, every objects fits on one + * line and we don't need the extra newline to help distinguish + */ + if (MTYPE_TRACK_TIDES > 0 || MTYPE_EXTRA_STATS > 0) + vty_out (vty, "%s", VTY_NEWLINE); + } } DEFUN (show_memory_all, @@ -383,6 +850,19 @@ DEFUN (show_memory_isis, void memory_init (void) { + struct mlist *ml; + struct memory_list *m; + + for (ml = mlists; ml->list; ml++) + { + for (m = ml->list; m->index >= 0; m++) + if (m->index > 0) + mstat[m->index].cacheable = m->cacheable; + } + + /* the 0th cache is special, for extremely lazy users, must be invalid */ + mstat[0].cache_used = -1; + install_element (VIEW_NODE, &show_memory_cmd); install_element (VIEW_NODE, &show_memory_all_cmd); install_element (VIEW_NODE, &show_memory_lib_cmd); Index: lib/memory.h =================================================================== RCS file: /var/cvsroot/quagga/lib/memory.h,v retrieving revision 1.13 diff -u -p -r1.13 memory.h --- lib/memory.h 6 May 2005 21:25:49 -0000 1.13 +++ lib/memory.h 11 Oct 2005 04:18:19 -0000 @@ -20,12 +20,16 @@ Software Foundation, Inc., 59 Temple Pla #ifndef _ZEBRA_MEMORY_H #define _ZEBRA_MEMORY_H +#include "vty.h" + +enum mtype_cacheable { MTYPE_NOCACHE = 0, MTYPE_CACHE = 1 }; /* For pretty printing of memory allocate information. */ struct memory_list { int index; const char *format; + enum mtype_cacheable cacheable; }; struct mlist { Index: lib/memtypes.c =================================================================== RCS file: /var/cvsroot/quagga/lib/memtypes.c,v retrieving revision 1.7 diff -u -p -r1.7 memtypes.c --- lib/memtypes.c 21 Sep 2005 14:06:35 -0000 1.7 +++ lib/memtypes.c 11 Oct 2005 04:18:19 -0000 @@ -14,233 +14,239 @@ struct memory_list memory_list_lib[] = { - { MTYPE_TMP, "Temporary memory" }, - { MTYPE_STRVEC, "String vector" }, - { MTYPE_VECTOR, "Vector" }, - { MTYPE_VECTOR_INDEX, "Vector index" }, - { MTYPE_LINK_LIST, "Link List" }, - { MTYPE_LINK_NODE, "Link Node" }, - { MTYPE_THREAD, "Thread" }, - { MTYPE_THREAD_MASTER, "Thread master" }, - { MTYPE_THREAD_STATS, "Thread stats" }, - { MTYPE_THREAD_FUNCNAME, "Thread function name" }, - { MTYPE_VTY, "VTY" }, - { MTYPE_VTY_OUT_BUF, "VTY output buffer" }, - { MTYPE_VTY_HIST, "VTY history" }, - { MTYPE_IF, "Interface" }, - { MTYPE_CONNECTED, "Connected" }, - { MTYPE_BUFFER, "Buffer" }, - { MTYPE_BUFFER_DATA, "Buffer data" }, - { MTYPE_STREAM, "Stream" }, - { MTYPE_STREAM_DATA, "Stream data" }, - { MTYPE_STREAM_FIFO, "Stream FIFO" }, - { MTYPE_PREFIX, "Prefix" }, - { MTYPE_PREFIX_IPV4, "Prefix IPv4" }, - { MTYPE_PREFIX_IPV6, "Prefix IPv6" }, - { MTYPE_HASH, "Hash" }, - { MTYPE_HASH_BACKET, "Hash Bucket" }, - { MTYPE_HASH_INDEX, "Hash Index" }, - { MTYPE_ROUTE_TABLE, "Route table" }, - { MTYPE_ROUTE_NODE, "Route node" }, - { MTYPE_DISTRIBUTE, "Distribute list" }, - { MTYPE_DISTRIBUTE_IFNAME, "Dist-list ifname" }, - { MTYPE_ACCESS_LIST, "Access List" }, - { MTYPE_ACCESS_LIST_STR, "Access List Str" }, - { MTYPE_ACCESS_FILTER, "Access Filter" }, - { MTYPE_PREFIX_LIST, "Prefix List" }, - { MTYPE_PREFIX_LIST_ENTRY, "Prefix List Entry" }, - { MTYPE_PREFIX_LIST_STR, "Prefix List Str" }, - { MTYPE_ROUTE_MAP, "Route map" }, - { MTYPE_ROUTE_MAP_NAME, "Route map name" }, - { MTYPE_ROUTE_MAP_INDEX, "Route map index" }, - { MTYPE_ROUTE_MAP_RULE, "Route map rule" }, - { MTYPE_ROUTE_MAP_RULE_STR, "Route map rule str" }, - { MTYPE_ROUTE_MAP_COMPILED, "Route map compiled" }, - { MTYPE_DESC, "Command desc" }, - { MTYPE_KEY, "Key" }, - { MTYPE_KEYCHAIN, "Key chain" }, - { MTYPE_IF_RMAP, "Interface route map" }, - { MTYPE_SOCKUNION, "Socket union" }, - { MTYPE_PRIVS, "Privilege information" }, - { MTYPE_ZLOG, "Logging" }, - { MTYPE_ZCLIENT, "Zclient" }, - { MTYPE_WORK_QUEUE, "Work queue" }, - { MTYPE_WORK_QUEUE_ITEM, "Work queue item" }, - { MTYPE_WORK_QUEUE_NAME, "Work queue name string" }, + { MTYPE_TMP, "Temporary memory", MTYPE_NOCACHE, }, + { MTYPE_STRVEC, "String vector", MTYPE_NOCACHE, }, + { MTYPE_VECTOR, "Vector", MTYPE_CACHE, }, + { MTYPE_VECTOR_INDEX, "Vector index", MTYPE_NOCACHE }, + { MTYPE_LINK_LIST, "Link List", MTYPE_CACHE }, + { MTYPE_LINK_NODE, "Link Node", MTYPE_CACHE }, + { MTYPE_THREAD, "Thread", MTYPE_CACHE }, + { MTYPE_THREAD_MASTER, "Thread master", MTYPE_CACHE }, + { MTYPE_THREAD_STATS, "Thread stats", MTYPE_NOCACHE }, + { MTYPE_THREAD_FUNCNAME, "Thread function name", MTYPE_NOCACHE }, + { MTYPE_VTY, "VTY", MTYPE_NOCACHE }, + { MTYPE_VTY_OUT_BUF, "VTY output buffer", MTYPE_NOCACHE }, + { MTYPE_VTY_HIST, "VTY history", MTYPE_CACHE }, + { MTYPE_IF, "Interface", MTYPE_CACHE }, + { MTYPE_CONNECTED, "Connected", MTYPE_CACHE }, + { MTYPE_BUFFER, "Buffer", MTYPE_CACHE }, + { MTYPE_BUFFER_DATA, "Buffer data", MTYPE_CACHE }, + { MTYPE_STREAM, "Stream", MTYPE_CACHE }, + { MTYPE_STREAM_DATA, "Stream data", MTYPE_NOCACHE }, + { MTYPE_STREAM_FIFO, "Stream FIFO", MTYPE_CACHE }, + { MTYPE_PREFIX, "Prefix", MTYPE_CACHE }, + { MTYPE_PREFIX_IPV4, "Prefix IPv4", MTYPE_NOCACHE }, + { MTYPE_PREFIX_IPV6, "Prefix IPv6", MTYPE_NOCACHE }, + { MTYPE_HASH, "Hash", MTYPE_CACHE }, + { MTYPE_HASH_BACKET, "Hash Bucket", MTYPE_CACHE }, + { MTYPE_HASH_INDEX, "Hash Index", MTYPE_CACHE }, + { MTYPE_ROUTE_TABLE, "Route table", MTYPE_CACHE }, + { MTYPE_ROUTE_NODE, "Route node", MTYPE_CACHE }, + { MTYPE_DISTRIBUTE, "Distribute list", MTYPE_NOCACHE }, + { MTYPE_DISTRIBUTE_IFNAME, "Dist-list ifname", MTYPE_NOCACHE }, + { MTYPE_ACCESS_LIST, "Access List", MTYPE_NOCACHE }, + { MTYPE_ACCESS_LIST_STR, "Access List Str", MTYPE_NOCACHE }, + { MTYPE_ACCESS_FILTER, "Access Filter", MTYPE_NOCACHE }, + { MTYPE_PREFIX_LIST, "Prefix List", MTYPE_NOCACHE }, + { MTYPE_PREFIX_LIST_ENTRY, "Prefix List Entry", MTYPE_NOCACHE }, + { MTYPE_PREFIX_LIST_STR, "Prefix List Str", MTYPE_NOCACHE }, + { MTYPE_ROUTE_MAP, "Route map", MTYPE_NOCACHE }, + { MTYPE_ROUTE_MAP_NAME, "Route map name", MTYPE_NOCACHE }, + { MTYPE_ROUTE_MAP_INDEX, "Route map index", MTYPE_NOCACHE }, + { MTYPE_ROUTE_MAP_RULE, "Route map rule", MTYPE_NOCACHE }, + { MTYPE_ROUTE_MAP_RULE_STR, "Route map rule str", MTYPE_NOCACHE }, + { MTYPE_ROUTE_MAP_COMPILED, "Route map compiled", MTYPE_NOCACHE }, + { MTYPE_DESC, "Command desc", MTYPE_NOCACHE }, + { MTYPE_KEY, "Key", MTYPE_NOCACHE }, + { MTYPE_KEYCHAIN, "Key chain", MTYPE_NOCACHE }, + { MTYPE_IF_RMAP, "Interface route map", MTYPE_NOCACHE }, + { MTYPE_IF_RMAP_NAME, "I.f. route map name", MTYPE_CACHE }, + { MTYPE_SOCKUNION, "Socket union", MTYPE_CACHE }, + { MTYPE_PRIVS, "Privilege information", MTYPE_NOCACHE }, + { MTYPE_ZLOG, "Logging", MTYPE_NOCACHE }, + { MTYPE_ZCLIENT, "Zclient", MTYPE_NOCACHE }, + { MTYPE_WORK_QUEUE, "Work queue", MTYPE_NOCACHE }, + { MTYPE_WORK_QUEUE_ITEM, "Work queue item", MTYPE_CACHE }, + { MTYPE_WORK_QUEUE_NAME, "Work queue name string", MTYPE_NOCACHE }, + { MTYPE_PQUEUE, "Priority queue", MTYPE_CACHE }, + { MTYPE_PQUEUE_DATA, "Priority queue data", MTYPE_CACHE }, + { MTYPE_HOST, "Host config", MTYPE_NOCACHE }, { -1, NULL }, }; struct memory_list memory_list_zebra[] = { - { MTYPE_RTADV_PREFIX, "Router Advertisement Prefix" }, - { MTYPE_VRF, "VRF" }, - { MTYPE_VRF_NAME, "VRF name" }, - { MTYPE_NEXTHOP, "Nexthop" }, - { MTYPE_RIB, "RIB" }, - { MTYPE_RIB_QUEUE, "RIB process work queue" }, - { MTYPE_STATIC_IPV4, "Static IPv4 route" }, - { MTYPE_STATIC_IPV6, "Static IPv6 route" }, + { MTYPE_RTADV_PREFIX, "Router Advertisement Prefix", MTYPE_NOCACHE }, + { MTYPE_VRF, "VRF", MTYPE_NOCACHE }, + { MTYPE_VRF_NAME, "VRF name", MTYPE_NOCACHE }, + { MTYPE_NEXTHOP, "Nexthop", MTYPE_CACHE }, + { MTYPE_RIB, "RIB", MTYPE_CACHE }, + { MTYPE_RIB_QUEUE, "RIB process work queue", MTYPE_CACHE }, + { MTYPE_STATIC_IPV4, "Static IPv4 route", MTYPE_NOCACHE }, + { MTYPE_STATIC_IPV6, "Static IPv6 route", MTYPE_NOCACHE }, { -1, NULL }, }; struct memory_list memory_list_bgp[] = { - { MTYPE_BGP, "BGP instance" }, - { MTYPE_BGP_PEER, "BGP peer" }, - { MTYPE_BGP_PEER_HOST, "BGP peer hostname" }, - { MTYPE_PEER_GROUP, "Peer group" }, - { MTYPE_PEER_DESC, "Peer description" }, - { MTYPE_ATTR, "BGP attribute" }, - { MTYPE_AS_PATH, "BGP aspath" }, - { MTYPE_AS_SEG, "BGP aspath seg" }, - { MTYPE_AS_SEG_DATA, "BGP aspath segment data" }, - { MTYPE_AS_STR, "BGP aspath str" }, - { 0, NULL }, - { MTYPE_BGP_TABLE, "BGP table" }, - { MTYPE_BGP_NODE, "BGP node" }, - { MTYPE_BGP_ROUTE, "BGP route" }, - { MTYPE_BGP_STATIC, "BGP static" }, - { MTYPE_BGP_ADVERTISE_ATTR, "BGP adv attr" }, - { MTYPE_BGP_ADVERTISE, "BGP adv" }, - { MTYPE_BGP_ADJ_IN, "BGP adj in" }, - { MTYPE_BGP_ADJ_OUT, "BGP adj out" }, - { 0, NULL }, - { MTYPE_AS_LIST, "BGP AS list" }, - { MTYPE_AS_FILTER, "BGP AS filter" }, - { MTYPE_AS_FILTER_STR, "BGP AS filter str" }, - { 0, NULL }, - { MTYPE_COMMUNITY, "community" }, - { MTYPE_COMMUNITY_VAL, "community val" }, - { MTYPE_COMMUNITY_STR, "community str" }, - { 0, NULL }, - { MTYPE_ECOMMUNITY, "extcommunity" }, - { MTYPE_ECOMMUNITY_VAL, "extcommunity val" }, - { MTYPE_ECOMMUNITY_STR, "extcommunity str" }, - { 0, NULL }, - { MTYPE_COMMUNITY_LIST, "community-list" }, - { MTYPE_COMMUNITY_LIST_NAME, "community-list name" }, - { MTYPE_COMMUNITY_LIST_ENTRY, "community-list entry" }, - { MTYPE_COMMUNITY_LIST_CONFIG, "community-list config" }, - { MTYPE_COMMUNITY_LIST_HANDLER, "community-list handler" }, - { 0, NULL }, - { MTYPE_CLUSTER, "Cluster list" }, - { MTYPE_CLUSTER_VAL, "Cluster list val" }, - { 0, NULL }, - { MTYPE_BGP_PROCESS_QUEUE, "BGP Process queue" }, - { MTYPE_BGP_CLEAR_NODE_QUEUE, "BGP node clear queue" }, - { 0, NULL }, - { MTYPE_TRANSIT, "BGP transit attr" }, - { MTYPE_TRANSIT_VAL, "BGP transit val" }, - { 0, NULL }, - { MTYPE_BGP_DISTANCE, "BGP distance" }, - { MTYPE_BGP_NEXTHOP_CACHE, "BGP nexthop" }, - { MTYPE_BGP_CONFED_LIST, "BGP confed list" }, - { MTYPE_PEER_UPDATE_SOURCE, "BGP peer update interface" }, - { MTYPE_BGP_DAMP_INFO, "Dampening info" }, - { MTYPE_BGP_DAMP_ARRAY, "BGP Dampening array" }, - { MTYPE_BGP_REGEXP, "BGP regexp" }, - { MTYPE_BGP_AGGREGATE, "BGP aggregate" }, + { MTYPE_BGP, "BGP instance", MTYPE_NOCACHE }, + { MTYPE_BGP_PEER, "BGP peer", MTYPE_CACHE }, + { MTYPE_BGP_PEER_HOST, "BGP peer hostname", MTYPE_NOCACHE }, + { MTYPE_PEER_GROUP, "Peer group", MTYPE_CACHE }, + { MTYPE_PEER_DESC, "Peer description", MTYPE_NOCACHE }, + { MTYPE_ATTR, "BGP attribute", MTYPE_CACHE }, + { MTYPE_AS_PATH, "BGP aspath", MTYPE_CACHE }, + { MTYPE_AS_SEG, "BGP aspath seg", MTYPE_CACHE }, + { MTYPE_AS_SEG_DATA, "BGP aspath segment data", MTYPE_NOCACHE }, + { MTYPE_AS_STR, "BGP aspath str", MTYPE_NOCACHE }, + { 0, NULL }, + { MTYPE_BGP_TABLE, "BGP table", MTYPE_CACHE }, + { MTYPE_BGP_NODE, "BGP node", MTYPE_CACHE }, + { MTYPE_BGP_ROUTE, "BGP route", MTYPE_CACHE }, + { MTYPE_BGP_STATIC, "BGP static", MTYPE_NOCACHE }, + { MTYPE_BGP_ADVERTISE_ATTR, "BGP adv attr", MTYPE_NOCACHE }, + { MTYPE_BGP_ADVERTISE, "BGP adv", MTYPE_NOCACHE }, + { MTYPE_BGP_ADJ_IN, "BGP adj in", MTYPE_CACHE }, + { MTYPE_BGP_ADJ_OUT, "BGP adj out", MTYPE_CACHE }, + { 0, NULL }, + { MTYPE_AS_LIST, "BGP AS list", MTYPE_NOCACHE }, + { MTYPE_AS_FILTER, "BGP AS filter", MTYPE_NOCACHE }, + { MTYPE_AS_FILTER_STR, "BGP AS filter str", MTYPE_NOCACHE }, + { 0, NULL }, + { MTYPE_COMMUNITY, "community", MTYPE_CACHE }, + { MTYPE_COMMUNITY_VAL, "community val", MTYPE_NOCACHE }, + { MTYPE_COMMUNITY_STR, "community str", MTYPE_NOCACHE }, + { 0, NULL }, + { MTYPE_ECOMMUNITY, "extcommunity", MTYPE_CACHE }, + { MTYPE_ECOMMUNITY_VAL, "extcommunity val", MTYPE_NOCACHE }, + { MTYPE_ECOMMUNITY_STR, "extcommunity str", MTYPE_NOCACHE }, + { 0, NULL }, + { MTYPE_COMMUNITY_LIST, "community-list", MTYPE_NOCACHE }, + { MTYPE_COMMUNITY_LIST_NAME, "community-list name", MTYPE_NOCACHE }, + { MTYPE_COMMUNITY_LIST_ENTRY, "community-list entry", MTYPE_NOCACHE }, + { MTYPE_COMMUNITY_LIST_CONFIG, "community-list config", MTYPE_NOCACHE }, + { MTYPE_COMMUNITY_LIST_HANDLER, "community-list handler", MTYPE_NOCACHE }, + { 0, NULL }, + { MTYPE_CLUSTER, "Cluster list", MTYPE_NOCACHE }, + { MTYPE_CLUSTER_VAL, "Cluster list val", MTYPE_NOCACHE }, + { 0, NULL }, + { MTYPE_BGP_PROCESS_QUEUE, "BGP Process queue", MTYPE_CACHE }, + { MTYPE_BGP_CLEAR_NODE_QUEUE, "BGP node clear queue", MTYPE_NOCACHE }, + { 0, NULL }, + { MTYPE_TRANSIT, "BGP transit attr", MTYPE_NOCACHE }, + { MTYPE_TRANSIT_VAL, "BGP transit val", MTYPE_NOCACHE }, + { 0, NULL }, + { MTYPE_BGP_DISTANCE, "BGP distance", MTYPE_NOCACHE }, + { MTYPE_BGP_NEXTHOP_CACHE, "BGP nexthop", MTYPE_CACHE }, + { MTYPE_BGP_CONFED_LIST, "BGP confed list", MTYPE_NOCACHE }, + { MTYPE_PEER_UPDATE_SOURCE, "BGP peer update interface", MTYPE_NOCACHE }, + { MTYPE_BGP_DAMP_INFO, "Dampening info", MTYPE_NOCACHE }, + { MTYPE_BGP_DAMP_ARRAY, "BGP Dampening array", MTYPE_NOCACHE }, + { MTYPE_BGP_REGEXP, "BGP regexp", MTYPE_NOCACHE }, + { MTYPE_BGP_AGGREGATE, "BGP aggregate", MTYPE_NOCACHE }, { -1, NULL } }; struct memory_list memory_list_rip[] = { - { MTYPE_RIP, "RIP structure" }, - { MTYPE_RIP_INFO, "RIP route info" }, - { MTYPE_RIP_INTERFACE, "RIP interface" }, - { MTYPE_RIP_PEER, "RIP peer" }, - { MTYPE_RIP_OFFSET_LIST, "RIP offset list" }, - { MTYPE_RIP_DISTANCE, "RIP distance" }, + { MTYPE_RIP, "RIP structure", MTYPE_NOCACHE }, + { MTYPE_RIP_INFO, "RIP route info", MTYPE_NOCACHE }, + { MTYPE_RIP_INTERFACE, "RIP interface", MTYPE_NOCACHE }, + { MTYPE_RIP_PEER, "RIP peer", MTYPE_NOCACHE }, + { MTYPE_RIP_OFFSET_LIST, "RIP offset list", MTYPE_NOCACHE }, + { MTYPE_RIP_DISTANCE, "RIP distance", MTYPE_NOCACHE }, { -1, NULL } }; struct memory_list memory_list_ripng[] = { - { MTYPE_RIPNG, "RIPng structure" }, - { MTYPE_RIPNG_ROUTE, "RIPng route info" }, - { MTYPE_RIPNG_AGGREGATE, "RIPng aggregate" }, - { MTYPE_RIPNG_PEER, "RIPng peer" }, - { MTYPE_RIPNG_OFFSET_LIST, "RIPng offset lst" }, - { MTYPE_RIPNG_RTE_DATA, "RIPng rte data" }, + { MTYPE_RIPNG, "RIPng structure", MTYPE_NOCACHE }, + { MTYPE_RIPNG_ROUTE, "RIPng route info", MTYPE_NOCACHE }, + { MTYPE_RIPNG_AGGREGATE, "RIPng aggregate", MTYPE_NOCACHE }, + { MTYPE_RIPNG_PEER, "RIPng peer", MTYPE_NOCACHE }, + { MTYPE_RIPNG_OFFSET_LIST, "RIPng offset lst", MTYPE_NOCACHE }, + { MTYPE_RIPNG_RTE_DATA, "RIPng rte data", MTYPE_NOCACHE }, { -1, NULL } }; struct memory_list memory_list_ospf[] = { - { MTYPE_OSPF_TOP, "OSPF top" }, - { MTYPE_OSPF_AREA, "OSPF area" }, - { MTYPE_OSPF_AREA_RANGE, "OSPF area range" }, - { MTYPE_OSPF_NETWORK, "OSPF network" }, - { MTYPE_OSPF_NEIGHBOR_STATIC,"OSPF static nbr" }, - { MTYPE_OSPF_IF, "OSPF interface" }, - { MTYPE_OSPF_NEIGHBOR, "OSPF neighbor" }, - { MTYPE_OSPF_ROUTE, "OSPF route" }, - { MTYPE_OSPF_TMP, "OSPF tmp mem" }, - { MTYPE_OSPF_LSA, "OSPF LSA" }, - { MTYPE_OSPF_LSA_DATA, "OSPF LSA data" }, - { MTYPE_OSPF_LSDB, "OSPF LSDB" }, - { MTYPE_OSPF_PACKET, "OSPF packet" }, - { MTYPE_OSPF_FIFO, "OSPF FIFO queue" }, - { MTYPE_OSPF_VERTEX, "OSPF vertex" }, - { MTYPE_OSPF_NEXTHOP, "OSPF nexthop" }, - { MTYPE_OSPF_PATH, "OSPF path" }, - { MTYPE_OSPF_VL_DATA, "OSPF VL data" }, - { MTYPE_OSPF_CRYPT_KEY, "OSPF crypt key" }, - { MTYPE_OSPF_EXTERNAL_INFO, "OSPF ext. info" }, - { MTYPE_OSPF_DISTANCE, "OSPF distance" }, - { MTYPE_OSPF_IF_INFO, "OSPF if info" }, - { MTYPE_OSPF_IF_PARAMS, "OSPF if params" }, - { MTYPE_OSPF_MESSAGE, "OSPF message" }, + { MTYPE_OSPF_TOP, "OSPF top", MTYPE_NOCACHE }, + { MTYPE_OSPF_AREA, "OSPF area", MTYPE_CACHE }, + { MTYPE_OSPF_AREA_RANGE, "OSPF area range", MTYPE_NOCACHE }, + { MTYPE_OSPF_NETWORK, "OSPF network", MTYPE_CACHE }, + { MTYPE_OSPF_NEIGHBOR_STATIC,"OSPF static nbr", MTYPE_NOCACHE }, + { MTYPE_OSPF_IF, "OSPF interface", MTYPE_CACHE }, + { MTYPE_OSPF_NEIGHBOR, "OSPF neighbor", MTYPE_CACHE }, + { MTYPE_OSPF_ROUTE, "OSPF route", MTYPE_CACHE }, + { MTYPE_OSPF_TMP, "OSPF tmp mem", MTYPE_NOCACHE }, + { MTYPE_OSPF_LSA, "OSPF LSA", MTYPE_CACHE }, + { MTYPE_OSPF_LSA_DATA, "OSPF LSA data", MTYPE_NOCACHE }, + { MTYPE_OSPF_LSDB, "OSPF LSDB", MTYPE_CACHE }, + { MTYPE_OSPF_PACKET, "OSPF packet", MTYPE_CACHE }, + { MTYPE_OSPF_FIFO, "OSPF FIFO queue", MTYPE_NOCACHE }, + { MTYPE_OSPF_VERTEX, "OSPF vertex", MTYPE_CACHE }, + { MTYPE_OSPF_VERTEX_PARENT, "OSPF vertex parent", MTYPE_CACHE }, + { MTYPE_OSPF_NEXTHOP, "OSPF nexthop", MTYPE_CACHE }, + { MTYPE_OSPF_PATH, "OSPF path", MTYPE_CACHE }, + { MTYPE_OSPF_VL_DATA, "OSPF VL data", MTYPE_NOCACHE }, + { MTYPE_OSPF_CRYPT_KEY, "OSPF crypt key", MTYPE_NOCACHE }, + { MTYPE_OSPF_EXTERNAL_INFO, "OSPF ext. info", MTYPE_NOCACHE }, + { MTYPE_OSPF_DISTANCE, "OSPF distance", MTYPE_NOCACHE }, + { MTYPE_OSPF_IF_INFO, "OSPF if info", MTYPE_NOCACHE }, + { MTYPE_OSPF_IF_PARAMS, "OSPF if params", MTYPE_NOCACHE }, + { MTYPE_OSPF_MESSAGE, "OSPF message", MTYPE_NOCACHE }, { -1, NULL }, }; struct memory_list memory_list_ospf6[] = { - { MTYPE_OSPF6_TOP, "OSPF6 top" }, - { MTYPE_OSPF6_AREA, "OSPF6 area" }, - { MTYPE_OSPF6_IF, "OSPF6 interface" }, - { MTYPE_OSPF6_NEIGHBOR, "OSPF6 neighbor" }, - { MTYPE_OSPF6_ROUTE, "OSPF6 route" }, - { MTYPE_OSPF6_PREFIX, "OSPF6 prefix" }, - { MTYPE_OSPF6_MESSAGE, "OSPF6 message" }, - { MTYPE_OSPF6_LSA, "OSPF6 LSA" }, - { MTYPE_OSPF6_LSA_SUMMARY, "OSPF6 LSA summary" }, - { MTYPE_OSPF6_LSDB, "OSPF6 LSA database" }, - { MTYPE_OSPF6_VERTEX, "OSPF6 vertex" }, - { MTYPE_OSPF6_SPFTREE, "OSPF6 SPF tree" }, - { MTYPE_OSPF6_NEXTHOP, "OSPF6 nexthop" }, - { MTYPE_OSPF6_EXTERNAL_INFO,"OSPF6 ext. info" }, - { MTYPE_OSPF6_OTHER, "OSPF6 other" }, + { MTYPE_OSPF6_TOP, "OSPF6 top", MTYPE_NOCACHE }, + { MTYPE_OSPF6_AREA, "OSPF6 area", MTYPE_NOCACHE }, + { MTYPE_OSPF6_IF, "OSPF6 interface", MTYPE_NOCACHE }, + { MTYPE_OSPF6_NEIGHBOR, "OSPF6 neighbor", MTYPE_NOCACHE }, + { MTYPE_OSPF6_ROUTE, "OSPF6 route", MTYPE_NOCACHE }, + { MTYPE_OSPF6_PREFIX, "OSPF6 prefix", MTYPE_NOCACHE }, + { MTYPE_OSPF6_MESSAGE, "OSPF6 message", MTYPE_NOCACHE }, + { MTYPE_OSPF6_LSA, "OSPF6 LSA", MTYPE_NOCACHE }, + { MTYPE_OSPF6_LSA_SUMMARY, "OSPF6 LSA summary", MTYPE_NOCACHE }, + { MTYPE_OSPF6_LSDB, "OSPF6 LSA database", MTYPE_NOCACHE }, + { MTYPE_OSPF6_VERTEX, "OSPF6 vertex", MTYPE_NOCACHE }, + { MTYPE_OSPF6_SPFTREE, "OSPF6 SPF tree", MTYPE_NOCACHE }, + { MTYPE_OSPF6_NEXTHOP, "OSPF6 nexthop", MTYPE_NOCACHE }, + { MTYPE_OSPF6_EXTERNAL_INFO,"OSPF6 ext. info", MTYPE_NOCACHE }, + { MTYPE_OSPF6_OTHER, "OSPF6 other", MTYPE_NOCACHE }, { -1, NULL }, }; struct memory_list memory_list_isis[] = { - { MTYPE_ISIS, "ISIS" }, - { MTYPE_ISIS_TMP, "ISIS TMP" }, - { MTYPE_ISIS_CIRCUIT, "ISIS circuit" }, - { MTYPE_ISIS_LSP, "ISIS LSP" }, - { MTYPE_ISIS_ADJACENCY, "ISIS adjacency" }, - { MTYPE_ISIS_AREA, "ISIS area" }, - { MTYPE_ISIS_AREA_ADDR, "ISIS area address" }, - { MTYPE_ISIS_TLV, "ISIS TLV" }, - { MTYPE_ISIS_DYNHN, "ISIS dyn hostname" }, - { MTYPE_ISIS_SPFTREE, "ISIS SPFtree" }, - { MTYPE_ISIS_VERTEX, "ISIS vertex" }, - { MTYPE_ISIS_ROUTE_INFO, "ISIS route info" }, - { MTYPE_ISIS_NEXTHOP, "ISIS nexthop" }, - { MTYPE_ISIS_NEXTHOP6, "ISIS nexthop6" }, + { MTYPE_ISIS, "ISIS", MTYPE_NOCACHE }, + { MTYPE_ISIS_TMP, "ISIS TMP", MTYPE_NOCACHE }, + { MTYPE_ISIS_CIRCUIT, "ISIS circuit", MTYPE_NOCACHE }, + { MTYPE_ISIS_LSP, "ISIS LSP", MTYPE_NOCACHE }, + { MTYPE_ISIS_ADJACENCY, "ISIS adjacency", MTYPE_NOCACHE }, + { MTYPE_ISIS_AREA, "ISIS area", MTYPE_NOCACHE }, + { MTYPE_ISIS_AREA_ADDR, "ISIS area address", MTYPE_NOCACHE }, + { MTYPE_ISIS_TLV, "ISIS TLV", MTYPE_NOCACHE }, + { MTYPE_ISIS_DYNHN, "ISIS dyn hostname", MTYPE_NOCACHE }, + { MTYPE_ISIS_SPFTREE, "ISIS SPFtree", MTYPE_NOCACHE }, + { MTYPE_ISIS_VERTEX, "ISIS vertex", MTYPE_CACHE }, + { MTYPE_ISIS_ROUTE_INFO, "ISIS route info", MTYPE_NOCACHE }, + { MTYPE_ISIS_NEXTHOP, "ISIS nexthop", MTYPE_NOCACHE }, + { MTYPE_ISIS_NEXTHOP6, "ISIS nexthop6", MTYPE_NOCACHE }, { -1, NULL }, }; struct memory_list memory_list_vtysh[] = { - { MTYPE_VTYSH_CONFIG, "Vtysh configuration", }, - { MTYPE_VTYSH_CONFIG_LINE, "Vtysh configuration line" }, + { MTYPE_VTYSH_CONFIG, "Vtysh configuration", MTYPE_NOCACHE }, + { MTYPE_VTYSH_CONFIG_LINE, "Vtysh configuration line", MTYPE_NOCACHE }, { -1, NULL }, }; -struct mlist mlists[] __attribute__ ((unused)) = { +struct mlist mlists[] __attribute__ ((unused)) = +{ { memory_list_lib, "LIB" }, { memory_list_zebra, "ZEBRA" }, { memory_list_rip, "RIP" }, Index: lib/pqueue.c =================================================================== RCS file: /var/cvsroot/quagga/lib/pqueue.c,v retrieving revision 1.3 diff -u -p -r1.3 pqueue.c --- lib/pqueue.c 6 May 2005 21:25:49 -0000 1.3 +++ lib/pqueue.c 11 Oct 2005 04:18:19 -0000 @@ -20,6 +20,7 @@ Boston, MA 02111-1307, USA. */ #include +#include "memory.h" #include "pqueue.h" /* priority queue using heap sort */ @@ -110,12 +111,10 @@ pqueue_create (void) { struct pqueue *queue; - queue = (struct pqueue *) malloc (sizeof (struct pqueue)); - memset (queue, 0, sizeof (struct pqueue)); + queue = XCALLOC (MTYPE_PQUEUE, sizeof (struct pqueue)); - queue->array = (void **) - malloc (DATA_SIZE * PQUEUE_INIT_ARRAYSIZE); - memset (queue->array, 0, DATA_SIZE * PQUEUE_INIT_ARRAYSIZE); + queue->array = XCALLOC (MTYPE_PQUEUE_DATA, + DATA_SIZE * PQUEUE_INIT_ARRAYSIZE); queue->array_size = PQUEUE_INIT_ARRAYSIZE; /* By default we want nothing to happen when a node changes. */ @@ -126,8 +125,8 @@ pqueue_create (void) void pqueue_delete (struct pqueue *queue) { - free (queue->array); - free (queue); + XFREE (MTYPE_PQUEUE_DATA, queue->array); + XFREE (MTYPE_PQUEUE, queue); } static int @@ -135,14 +134,13 @@ pqueue_expand (struct pqueue *queue) { void **newarray; - newarray = (void **) malloc (queue->array_size * DATA_SIZE * 2); + newarray = XCALLOC (MTYPE_PQUEUE_DATA, queue->array_size * DATA_SIZE * 2); if (newarray == NULL) return 0; - memset (newarray, 0, queue->array_size * DATA_SIZE * 2); memcpy (newarray, queue->array, queue->array_size * DATA_SIZE); - free (queue->array); + XFREE (MTYPE_PQUEUE_DATA, queue->array); queue->array = newarray; queue->array_size *= 2; Index: lib/routemap.c =================================================================== RCS file: /var/cvsroot/quagga/lib/routemap.c,v retrieving revision 1.14 diff -u -p -r1.14 routemap.c --- lib/routemap.c 29 Sep 2005 11:25:50 -0000 1.14 +++ lib/routemap.c 11 Oct 2005 04:18:19 -0000 @@ -314,7 +314,7 @@ route_map_index_delete (struct route_map /* Free 'char *nextrm' if not NULL */ if (index->nextrm) - free (index->nextrm); + XFREE (MTYPE_ROUTE_MAP_NAME, index->nextrm); /* Execute event hook. */ if (route_map_master.event_hook && notify) @@ -1175,8 +1175,8 @@ DEFUN (rmap_call, if (index) { if (index->nextrm) - free (index->nextrm); - index->nextrm = strdup (argv[0]); + XFREE (MTYPE_ROUTE_MAP_NAME, index->nextrm); + index->nextrm = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[0]); } return CMD_SUCCESS; } @@ -1193,7 +1193,7 @@ DEFUN (no_rmap_call, if (index->nextrm) { - free (index->nextrm); + XFREE (MTYPE_ROUTE_MAP_NAME, index->nextrm); index->nextrm = NULL; } Index: lib/stream.c =================================================================== RCS file: /var/cvsroot/quagga/lib/stream.c,v retrieving revision 1.10 diff -u -p -r1.10 stream.c --- lib/stream.c 3 May 2005 09:07:56 -0000 1.10 +++ lib/stream.c 11 Oct 2005 04:18:19 -0000 @@ -99,12 +99,18 @@ stream_new (size_t size) return NULL; } - s = XCALLOC (MTYPE_STREAM, offsetof(struct stream, data[size])); + s = XCALLOC (MTYPE_STREAM, sizeof (struct stream)); if (s == NULL) return s; + if ( (s->data = XMALLOC (MTYPE_STREAM_DATA, size)) == NULL) + { + XFREE (MTYPE_STREAM, s); + return NULL; + } s->size = size; + return s; } @@ -112,6 +118,10 @@ stream_new (size_t size) void stream_free (struct stream *s) { + if (!s) + return; + + XFREE (MTYPE_STREAM_DATA, s->data); XFREE (MTYPE_STREAM, s); } Index: lib/stream.h =================================================================== RCS file: /var/cvsroot/quagga/lib/stream.h,v retrieving revision 1.9 diff -u -p -r1.9 stream.h --- lib/stream.h 6 May 2005 21:25:49 -0000 1.9 +++ lib/stream.h 11 Oct 2005 04:18:19 -0000 @@ -103,7 +103,7 @@ struct stream size_t getp; /* next get position */ size_t endp; /* last valid data position */ size_t size; /* size of data segment */ - unsigned char data[0]; /* data pointer */ + unsigned char *data; /* data pointer */ }; /* First in first out queue structure. */ Index: lib/vty.c =================================================================== RCS file: /var/cvsroot/quagga/lib/vty.c,v retrieving revision 1.46 diff -u -p -r1.46 vty.c --- lib/vty.c 29 Sep 2005 11:25:50 -0000 1.46 +++ lib/vty.c 11 Oct 2005 04:18:20 -0000 @@ -2306,6 +2306,7 @@ vty_read_config (char *config_file, char cwd[MAXPATHLEN]; FILE *confp = NULL; char *fullpath; + char *tmp = NULL; /* If -f flag specified. */ if (config_file != NULL) @@ -2313,9 +2314,10 @@ vty_read_config (char *config_file, if (! IS_DIRECTORY_SEP (config_file[0])) { getcwd (cwd, MAXPATHLEN); - fullpath = XMALLOC (MTYPE_TMP, + tmp = XMALLOC (MTYPE_TMP, strlen (cwd) + strlen (config_file) + 2); - sprintf (fullpath, "%s/%s", cwd, config_file); + sprintf (tmp, "%s/%s", cwd, config_file); + fullpath = tmp; } else fullpath = config_file; @@ -2394,6 +2396,9 @@ vty_read_config (char *config_file, fclose (confp); host_config_set (fullpath); + + if (tmp) + XFREE (MTYPE_TMP, fullpath); } /* Small utility function which output log to the VTY. */