diff options
Diffstat (limited to 'lib')
48 files changed, 782 insertions, 1098 deletions
diff --git a/lib/.gitignore b/lib/.gitignore index 8174bda7d8..e45fec1786 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -14,7 +14,6 @@ gitversion.h.tmp .arch-ids *~ *.loT -memtypes.h route_types.h command_lex.c command_parse.c diff --git a/lib/Makefile.am b/lib/Makefile.am index 3dfd09e2e6..acaf7e6744 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -13,13 +13,13 @@ libzebra_la_SOURCES = \ checksum.c vector.c linklist.c vty.c \ graph.c command_parse.y command_lex.l command_match.c \ command.c \ - sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \ + sockunion.c prefix.c thread.c if.c buffer.c table.c hash.c \ filter.c routemap.c distribute.c stream.c str.c log.c plist.c \ zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \ - sigevent.c pqueue.c jhash.c memtypes.c workqueue.c nexthop.c json.c \ - ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c + sigevent.c pqueue.c jhash.c workqueue.c nexthop.c json.c \ + ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c memory.c memory_vty.c -BUILT_SOURCES = memtypes.h route_types.h gitversion.h command_parse.h +BUILT_SOURCES = route_types.h gitversion.h command_parse.h libzebra_la_DEPENDENCIES = @LIB_REGEX@ @@ -33,9 +33,10 @@ pkginclude_HEADERS = \ memory.h network.h prefix.h routemap.h distribute.h sockunion.h \ str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \ plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \ - privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \ + privs.h sigevent.h pqueue.h jhash.h zassert.h \ workqueue.h route_types.h libospf.h nexthop.h json.h \ - ptm_lib.h csv.h bfd.h vrf.h ns.h systemd.h bitfield.h + ptm_lib.h csv.h bfd.h vrf.h ns.h systemd.h bitfield.h \ + fifo.h memory_vty.h noinst_HEADERS = \ plist_int.h @@ -43,13 +44,9 @@ noinst_HEADERS = \ EXTRA_DIST = \ regex.c regex-gnu.h \ queue.h \ - memtypes.awk \ route_types.pl route_types.txt \ gitversion.pl -memtypes.h: $(srcdir)/memtypes.c $(srcdir)/memtypes.awk - ($(GAWK) -f $(srcdir)/memtypes.awk $(srcdir)/memtypes.c > $@) - route_types.h: $(srcdir)/route_types.txt $(srcdir)/route_types.pl @PERL@ $(srcdir)/route_types.pl < $(srcdir)/route_types.txt > $@ @@ -33,6 +33,8 @@ #include "vty.h" #include "bfd.h" +DEFINE_MTYPE_STATIC(LIB, BFD_INFO, "BFD info") + int bfd_debug = 0; struct bfd_gbl bfd_gbl; diff --git a/lib/buffer.c b/lib/buffer.c index ee9310100e..1dfcdb4732 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -28,7 +28,8 @@ #include "network.h" #include <stddef.h> - +DEFINE_MTYPE_STATIC(LIB, BUFFER, "Buffer") +DEFINE_MTYPE_STATIC(LIB, BUFFER_DATA, "Buffer data") /* Buffer master. */ struct buffer diff --git a/lib/command.c b/lib/command.c index b4ef30a300..b6f97c317e 100644 --- a/lib/command.c +++ b/lib/command.c @@ -34,10 +34,13 @@ Boston, MA 02111-1307, USA. */ #include "command.h" #include "workqueue.h" #include "vrf.h" - #include "command_match.h" #include "command_parse.h" +DEFINE_MTYPE( LIB, HOST, "Host config") +DEFINE_MTYPE( LIB, STRVEC, "String vector") +DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc") + /* Command vector which includes some level of command lists. Normally each daemon maintains each own cmdvec. */ vector cmdvec = NULL; diff --git a/lib/command.h b/lib/command.h index 5e1b48c68f..ddb61c686f 100644 --- a/lib/command.h +++ b/lib/command.h @@ -27,6 +27,12 @@ #include "vty.h" #include "lib/route_types.h" #include "graph.h" +#include "memory.h" + +DECLARE_MTYPE(HOST) + +/* for test-commands.c */ +DECLARE_MTYPE(STRVEC) /* Host configuration variable */ struct host diff --git a/lib/command_match.c b/lib/command_match.c index d7c2222ce6..dd68ca477e 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -23,10 +23,13 @@ */ #include <zebra.h> + #include "command_match.h" #include "command_parse.h" #include "memory.h" +DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens") + /* matcher helper prototypes */ static int add_nexthops (struct list *, struct graph_node *); diff --git a/lib/command_parse.y b/lib/command_parse.y index 089b506b03..6a5d75aabf 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -33,9 +33,10 @@ /* required external units */ %code requires { + #include "stdlib.h" + #include "string.h" #include "command.h" #include "graph.h" - #include "memory.h" extern int yylex (void); @@ -145,7 +146,7 @@ set_lexer_string (element->string); /* copy docstring and keep a pointer to the copy */ - docstr = element->doc ? XSTRDUP(MTYPE_TMP, element->doc) : NULL; + docstr = element->doc ? strdup(element->doc) : NULL; docstr_start = docstr; } @@ -174,7 +175,7 @@ start: sentence_root: WORD { struct graph_node *root = - new_token_node (graph, WORD_TKN, XSTRDUP (MTYPE_CMD_TOKENS, $1), doc_next()); + new_token_node (graph, WORD_TKN, strdup ($1), doc_next()); if ((currnode = add_edge_dedup (startnode, root)) != root) graph_delete_node (graph, root); @@ -199,7 +200,7 @@ cmd_token: { graph_add_edge (currnode, $1->start); currnode = $1->end; - XFREE (MTYPE_TMP, $1); + free ($1); } ; @@ -215,7 +216,7 @@ compound_token: literal_token: WORD { - $$ = new_token_node (graph, WORD_TKN, XSTRDUP(MTYPE_CMD_TOKENS, $1), doc_next()); + $$ = new_token_node (graph, WORD_TKN, strdup($1), doc_next()); free ($1); } ; @@ -223,32 +224,32 @@ literal_token: WORD placeholder_token: IPV4 { - $$ = new_token_node (graph, IPV4_TKN, XSTRDUP(MTYPE_CMD_TOKENS, $1), doc_next()); + $$ = new_token_node (graph, IPV4_TKN, strdup($1), doc_next()); free ($1); } | IPV4_PREFIX { - $$ = new_token_node (graph, IPV4_PREFIX_TKN, XSTRDUP(MTYPE_CMD_TOKENS, $1), doc_next()); + $$ = new_token_node (graph, IPV4_PREFIX_TKN, strdup($1), doc_next()); free ($1); } | IPV6 { - $$ = new_token_node (graph, IPV6_TKN, XSTRDUP(MTYPE_CMD_TOKENS, $1), doc_next()); + $$ = new_token_node (graph, IPV6_TKN, strdup($1), doc_next()); free ($1); } | IPV6_PREFIX { - $$ = new_token_node (graph, IPV6_PREFIX_TKN, XSTRDUP(MTYPE_CMD_TOKENS, $1), doc_next()); + $$ = new_token_node (graph, IPV6_PREFIX_TKN, strdup($1), doc_next()); free ($1); } | VARIABLE { - $$ = new_token_node (graph, VARIABLE_TKN, XSTRDUP(MTYPE_CMD_TOKENS, $1), doc_next()); + $$ = new_token_node (graph, VARIABLE_TKN, strdup($1), doc_next()); free ($1); } | RANGE { - $$ = new_token_node (graph, RANGE_TKN, XSTRDUP(MTYPE_CMD_TOKENS, $1), doc_next()); + $$ = new_token_node (graph, RANGE_TKN, strdup($1), doc_next()); struct cmd_token *token = $$->data; // get the numbers out @@ -266,7 +267,7 @@ placeholder_token: /* <selector|set> productions */ selector: '<' selector_seq_seq '>' { - $$ = XMALLOC (MTYPE_TMP, sizeof (struct subgraph)); + $$ = malloc (sizeof (struct subgraph)); $$->start = new_token_node (graph, SELECTOR_TKN, NULL, NULL); $$->end = new_token_node (graph, NUL_TKN, NULL, NULL); for (unsigned int i = 0; i < vector_active ($2->start->to); i++) @@ -278,20 +279,20 @@ selector: '<' selector_seq_seq '>' } graph_delete_node (graph, $2->start); graph_delete_node (graph, $2->end); - XFREE (MTYPE_TMP, $2); + free ($2); }; selector_seq_seq: selector_seq_seq '|' selector_token_seq { - $$ = XMALLOC (MTYPE_TMP, sizeof (struct subgraph)); + $$ = malloc (sizeof (struct subgraph)); $$->start = graph_new_node (graph, NULL, NULL); $$->end = graph_new_node (graph, NULL, NULL); // link in last sequence graph_add_edge ($$->start, $3->start); graph_add_edge ($3->end, $$->end); - XFREE (MTYPE_TMP, $3); + free ($3); for (unsigned int i = 0; i < vector_active ($1->start->to); i++) { @@ -302,44 +303,44 @@ selector_seq_seq: } graph_delete_node (graph, $1->start); graph_delete_node (graph, $1->end); - XFREE (MTYPE_TMP, $1); - XFREE (MTYPE_TMP, $3); + free ($1); + free ($3); } | selector_token_seq '|' selector_token_seq { - $$ = XMALLOC (MTYPE_TMP, sizeof (struct subgraph)); + $$ = malloc (sizeof (struct subgraph)); $$->start = graph_new_node (graph, NULL, NULL); $$->end = graph_new_node (graph, NULL, NULL); graph_add_edge ($$->start, $1->start); graph_add_edge ($1->end, $$->end); graph_add_edge ($$->start, $3->start); graph_add_edge ($3->end, $$->end); - XFREE (MTYPE_TMP, $1); - XFREE (MTYPE_TMP, $3); + free ($1); + free ($3); } ; selector_token_seq: simple_token { - $$ = XMALLOC (MTYPE_TMP, sizeof (struct subgraph)); + $$ = malloc (sizeof (struct subgraph)); $$->start = $$->end = $1; } | selector_token_seq selector_token { - $$ = XMALLOC (MTYPE_TMP, sizeof (struct subgraph)); + $$ = malloc (sizeof (struct subgraph)); graph_add_edge ($1->end, $2->start); $$->start = $1->start; $$->end = $2->end; - XFREE (MTYPE_TMP, $1); - XFREE (MTYPE_TMP, $2); + free ($1); + free ($2); } ; selector_token: simple_token { - $$ = XMALLOC (MTYPE_TMP, sizeof (struct subgraph)); + $$ = malloc (sizeof (struct subgraph)); $$->start = $$->end = $1; } | option @@ -349,7 +350,7 @@ selector_token: option: '[' option_token_seq ']' { // make a new option - $$ = XMALLOC (MTYPE_TMP, sizeof (struct subgraph)); + $$ = malloc (sizeof (struct subgraph)); $$->start = new_token_node (graph, OPTION_TKN, NULL, NULL); $$->end = new_token_node (graph, NUL_TKN, NULL, NULL); // add a path through the sequence to the end @@ -357,7 +358,7 @@ option: '[' option_token_seq ']' graph_add_edge ($2->end, $$->end); // add a path directly from the start to the end graph_add_edge ($$->start, $$->end); - XFREE (MTYPE_TMP, $2); + free ($2); } ; @@ -365,18 +366,18 @@ option_token_seq: option_token | option_token_seq option_token { - $$ = XMALLOC (MTYPE_TMP, sizeof (struct subgraph)); + $$ = malloc (sizeof (struct subgraph)); graph_add_edge ($1->end, $2->start); $$->start = $1->start; $$->end = $2->end; - XFREE (MTYPE_TMP, $1); + free ($1); } ; option_token: simple_token { - $$ = XMALLOC (MTYPE_TMP, sizeof (struct subgraph)); + $$ = malloc (sizeof (struct subgraph)); $$->start = $$->end = $1; } | compound_token @@ -429,8 +430,8 @@ terminate_graph (struct graph *graph, struct graph_node *finalnode, struct cmd_e struct graph_node *end_token_node = new_token_node (graph, END_TKN, - XSTRDUP (MTYPE_CMD_TOKENS, CMD_CR_TEXT), - XSTRDUP (MTYPE_CMD_TOKENS, "")); + strdup (CMD_CR_TEXT), + strdup ("")); struct graph_node *end_element_node = graph_new_node (graph, element, (void (*)(void *)) &del_cmd_element); @@ -446,8 +447,8 @@ doc_next() { char *piece = NULL; if (!docstr || !(piece = strsep (&docstr, "\n"))) - return XSTRDUP (MTYPE_CMD_TOKENS, ""); - return XSTRDUP (MTYPE_CMD_TOKENS, piece); + return strdup (""); + return strdup (piece); } static struct graph_node * diff --git a/lib/distribute.c b/lib/distribute.c index 757525fd71..d0d637fbb4 100644 --- a/lib/distribute.c +++ b/lib/distribute.c @@ -28,6 +28,10 @@ #include "distribute.h" #include "memory.h" +DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list") +DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname") +DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name") + /* Hash of distribute list. */ struct hash *disthash; diff --git a/lib/fifo.h b/lib/fifo.h new file mode 100644 index 0000000000..6be75b7611 --- /dev/null +++ b/lib/fifo.h @@ -0,0 +1,62 @@ +/* FIFO common header. + Copyright (C) 2015 Kunihiro Ishiguro + +This file is part of Quagga. + +Quagga is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Quagga is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Zebra; see the file COPYING. If not, write to the Free +Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +#ifndef __LIB_FIFO_H__ +#define __LIB_FIFO_H__ + +/* FIFO -- first in first out structure and macros. */ +struct fifo +{ + struct fifo *next; + struct fifo *prev; +}; + +#define FIFO_INIT(F) \ + do { \ + struct fifo *Xfifo = (struct fifo *)(F); \ + Xfifo->next = Xfifo->prev = Xfifo; \ + } while (0) + +#define FIFO_ADD(F,N) \ + do { \ + struct fifo *Xfifo = (struct fifo *)(F); \ + struct fifo *Xnode = (struct fifo *)(N); \ + Xnode->next = Xfifo; \ + Xnode->prev = Xfifo->prev; \ + Xfifo->prev = Xfifo->prev->next = Xnode; \ + } while (0) + +#define FIFO_DEL(N) \ + do { \ + struct fifo *Xnode = (struct fifo *)(N); \ + Xnode->prev->next = Xnode->next; \ + Xnode->next->prev = Xnode->prev; \ + } while (0) + +#define FIFO_HEAD(F) \ + ((((struct fifo *)(F))->next == (struct fifo *)(F)) \ + ? NULL : (F)->next) + +#define FIFO_EMPTY(F) \ + (((struct fifo *)(F))->next == (struct fifo *)(F)) + +#define FIFO_TOP(F) \ + (FIFO_EMPTY(F) ? NULL : ((struct fifo *)(F))->next) + +#endif /* __LIB_FIFO_H__ */ diff --git a/lib/filter.c b/lib/filter.c index 0eeb8f1872..e9ba715c92 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -30,6 +30,10 @@ #include "log.h" #include "routemap.h" +DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST, "Access List") +DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST_STR, "Access List Str") +DEFINE_MTYPE_STATIC(LIB, ACCESS_FILTER, "Access Filter") + struct filter_cisco { /* Cisco access-list */ diff --git a/lib/graph.c b/lib/graph.c index 7c59fe95b5..891ecc33c0 100644 --- a/lib/graph.c +++ b/lib/graph.c @@ -25,6 +25,8 @@ #include "graph.h" #include "memory.h" +DEFINE_MTYPE_STATIC(LIB, GRAPH, "Graph") +DEFINE_MTYPE_STATIC(LIB, GRAPH_NODE, "Graph Node") struct graph * graph_new () { diff --git a/lib/hash.c b/lib/hash.c index a20093cd64..cb8531fccf 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -24,6 +24,10 @@ #include "hash.h" #include "memory.h" +DEFINE_MTYPE( LIB, HASH, "Hash") +DEFINE_MTYPE( LIB, HASH_BACKET, "Hash Bucket") +DEFINE_MTYPE_STATIC(LIB, HASH_INDEX, "Hash Index") + /* Allocate a new hash. */ struct hash * hash_create_size (unsigned int size, unsigned int (*hash_key) (void *), diff --git a/lib/hash.h b/lib/hash.h index 0bc3089f34..11ecf75ec9 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -21,6 +21,11 @@ Boston, MA 02111-1307, USA. */ #ifndef _ZEBRA_HASH_H #define _ZEBRA_HASH_H +#include "memory.h" + +DECLARE_MTYPE(HASH) +DECLARE_MTYPE(HASH_BACKET) + /* Default hash table size. */ #define HASH_INITIAL_SIZE 256 /* initial number of backets. */ #define HASH_THRESHOLD 10 /* expand when backet. */ @@ -37,6 +37,12 @@ #include "str.h" #include "log.h" +DEFINE_MTYPE( LIB, IF, "Interface") +DEFINE_MTYPE_STATIC(LIB, CONNECTED, "Connected") +DEFINE_MTYPE_STATIC(LIB, NBR_CONNECTED, "Neighbor Connected") +DEFINE_MTYPE( LIB, CONNECTED_LABEL, "Connected interface label") +DEFINE_MTYPE_STATIC(LIB, IF_LINK_PARAMS, "Informational Link Parameters") + /* List of interfaces in only the default VRF */ int ptm_enable = 0; @@ -23,6 +23,10 @@ Boston, MA 02111-1307, USA. */ #include "zebra.h" #include "linklist.h" +#include "memory.h" + +DECLARE_MTYPE(IF) +DECLARE_MTYPE(CONNECTED_LABEL) /* Interface link-layer type, if known. Derived from: * diff --git a/lib/if_rmap.c b/lib/if_rmap.c index f2d76c69d6..736f2e237d 100644 --- a/lib/if_rmap.c +++ b/lib/if_rmap.c @@ -27,6 +27,9 @@ #include "if.h" #include "if_rmap.h" +DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map") +DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name") + struct hash *ifrmaphash; /* Hook functions. */ diff --git a/lib/json.h b/lib/json.h index 561f7cc405..5dbad601a3 100644 --- a/lib/json.h +++ b/lib/json.h @@ -40,4 +40,6 @@ extern void json_object_boolean_true_add(struct json_object* obj, extern struct json_object* json_object_lock(struct json_object *obj); extern void json_object_free(struct json_object *obj); +#define JSON_STR "JavaScript Object Notation\n" + #endif /* _QUAGGA_JSON_H */ diff --git a/lib/keychain.c b/lib/keychain.c index c4a007edd0..ac2083cf4b 100644 --- a/lib/keychain.c +++ b/lib/keychain.c @@ -25,6 +25,9 @@ Boston, MA 02111-1307, USA. */ #include "linklist.h" #include "keychain.h" +DEFINE_MTYPE_STATIC(LIB, KEY, "Key") +DEFINE_MTYPE_STATIC(LIB, KEYCHAIN, "Key chain") + /* Master list of key chain. */ struct list *keychain_list; diff --git a/lib/linklist.c b/lib/linklist.c index d27a2da848..6fe91c75fc 100644 --- a/lib/linklist.c +++ b/lib/linklist.c @@ -24,6 +24,9 @@ #include "linklist.h" #include "memory.h" +DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List") +DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node") + /* Allocate new list. */ struct list * list_new (void) @@ -35,6 +35,8 @@ #include <ucontext.h> #endif +DEFINE_MTYPE_STATIC(LIB, ZLOG, "Logging") + static int logfile_fd = -1; /* Used in signal handler. */ struct zlog *zlog_default = NULL; @@ -680,6 +682,14 @@ _zlog_assert_failed (const char *assertion, const char *file, abort(); } +void +memory_oom (size_t size, const char *name) +{ + zlog_err("out of memory: failed to allocate %zu bytes for %s" + "object", size, name); + zlog_backtrace(LOG_ERR); + abort(); +} /* Open log stream */ struct zlog * @@ -898,11 +908,6 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY (ZEBRA_REDISTRIBUTE_DELETE), DESC_ENTRY (ZEBRA_REDISTRIBUTE_DEFAULT_ADD), DESC_ENTRY (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE), - DESC_ENTRY (ZEBRA_IPV4_NEXTHOP_LOOKUP), - DESC_ENTRY (ZEBRA_IPV6_NEXTHOP_LOOKUP), - DESC_ENTRY (ZEBRA_IPV4_IMPORT_LOOKUP), - DESC_ENTRY (ZEBRA_IPV6_IMPORT_LOOKUP), - DESC_ENTRY (ZEBRA_INTERFACE_RENAME), DESC_ENTRY (ZEBRA_ROUTER_ID_ADD), DESC_ENTRY (ZEBRA_ROUTER_ID_DELETE), DESC_ENTRY (ZEBRA_ROUTER_ID_UPDATE), diff --git a/lib/memory.c b/lib/memory.c index 8d1a03743e..38e424da7d 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -1,487 +1,149 @@ /* - * Memory management routine - * Copyright (C) 1998 Kunihiro Ishiguro + * Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc. * - * This file is part of GNU Zebra. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * GNU Zebra is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * GNU Zebra is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Zebra; see the file COPYING. If not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #include <zebra.h> -/* malloc.h is generally obsolete, however GNU Libc mallinfo wants it. */ -#if !defined(HAVE_STDLIB_H) || (defined(GNU_LINUX) && defined(HAVE_MALLINFO)) -#include <malloc.h> -#endif /* !HAVE_STDLIB_H || HAVE_MALLINFO */ -#include "log.h" +#include <stdlib.h> + #include "memory.h" -static void alloc_inc (int); -static void alloc_dec (int); -static void log_memstats(int log_priority); +static struct memgroup *mg_first = NULL; +struct memgroup **mg_insert = &mg_first; -static const struct message mstr [] = -{ - { MTYPE_THREAD, "thread" }, - { MTYPE_THREAD_MASTER, "thread_master" }, - { MTYPE_VECTOR, "vector" }, - { MTYPE_VECTOR_INDEX, "vector_index" }, - { MTYPE_IF, "interface" }, - { 0, NULL }, -}; - -/* Fatal memory allocation error occured. */ -static void __attribute__ ((noreturn)) -zerror (const char *fname, int type, size_t size) -{ - zlog_err ("%s : can't allocate memory for `%s' size %d: %s\n", - fname, lookup (mstr, type), (int) size, safe_strerror(errno)); - log_memstats(LOG_WARNING); - /* N.B. It might be preferable to call zlog_backtrace_sigsafe here, since - that function should definitely be safe in an OOM condition. But - unfortunately zlog_backtrace_sigsafe does not support syslog logging at - this time... */ - zlog_backtrace(LOG_WARNING); - abort(); -} +DEFINE_MGROUP(LIB, "libzebra") +DEFINE_MTYPE(LIB, TMP, "Temporary memory") -/* - * Allocate memory of a given size, to be tracked by a given type. - * Effects: Returns a pointer to usable memory. If memory cannot - * be allocated, aborts execution. - */ -void * -zmalloc (int type, size_t size) +static inline void +mt_count_alloc (struct memtype *mt, size_t size) { - void *memory; - - memory = malloc (size); + mt->n_alloc++; - if (memory == NULL) - zerror ("malloc", type, size); - - alloc_inc (type); - - return memory; + if (mt->size == 0) + mt->size = size; + else if (mt->size != size) + mt->size = SIZE_VAR; } -/* - * Allocate memory as in zmalloc, and also clear the memory. - * Add an extra 'z' prefix to function name to avoid collision when linking - * statically with zlib that exports the 'zcalloc' symbol. - */ -void * -zzcalloc (int type, size_t size) +static inline void +mt_count_free (struct memtype *mt) { - void *memory; - - memory = calloc (1, size); - - if (memory == NULL) - zerror ("calloc", type, size); - - alloc_inc (type); - - return memory; + mt->n_alloc--; } -/* - * Given a pointer returned by zmalloc or zzcalloc, free it and - * return a pointer to a new size, basically acting like realloc(). - * Requires: ptr was returned by zmalloc, zzcalloc, or zrealloc with the - * same type. - * Effects: Returns a pointer to the new memory, or aborts. - */ -void * -zrealloc (int type, void *ptr, size_t size) +static inline void * +mt_checkalloc (struct memtype *mt, void *ptr, size_t size) { - void *memory; - - if (ptr == NULL) /* is really alloc */ - return zzcalloc(type, size); - - memory = realloc (ptr, size); - if (memory == NULL) - zerror ("realloc", type, size); - if (ptr == NULL) - alloc_inc (type); - - return memory; -} - -/* - * Free memory allocated by z*alloc or zstrdup. - * Requires: ptr was returned by zmalloc, zzcalloc, or zrealloc with the - * same type. - * Effects: The memory is freed and may no longer be referenced. - */ -void -zfree (int type, void *ptr) -{ - if (ptr != NULL) + if (__builtin_expect(ptr == NULL, 0)) { - alloc_dec (type); - free (ptr); + memory_oom (size, mt->name); + return NULL; } -} - -/* - * Duplicate a string, counting memory usage by type. - * Effects: The string is duplicated, and the return value must - * eventually be passed to zfree with the same type. The function will - * succeed or abort. - */ -char * -zstrdup (int type, const char *str) -{ - void *dup; - - dup = strdup (str); - if (dup == NULL) - zerror ("strdup", type, strlen (str)); - alloc_inc (type); - return dup; -} - -#ifdef MEMORY_LOG -static struct -{ - const char *name; - 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) -{ - zlog_debug ("%s: %s %p %s %d", func, lookup (mstr, type), memory, file, line); + mt_count_alloc (mt, size); + return ptr; } void * -mtype_zmalloc (const char *file, int line, int type, size_t size) +qmalloc (struct memtype *mt, size_t size) { - void *memory; - - mstat[type].c_malloc++; - mstat[type].t_malloc++; - - memory = zmalloc (type, size); - mtype_log ("zmalloc", memory, file, line, type); - - return memory; + return mt_checkalloc (mt, malloc (size), size); } void * -mtype_zcalloc (const char *file, int line, int type, size_t size) +qcalloc (struct memtype *mt, size_t size) { - void *memory; - - mstat[type].c_calloc++; - mstat[type].t_calloc++; - - memory = zzcalloc (type, size); - mtype_log ("xcalloc", memory, file, line, type); - - return memory; + return mt_checkalloc (mt, calloc (size, 1), size); } void * -mtype_zrealloc (const char *file, int line, int type, void *ptr, size_t size) -{ - void *memory; - - /* Realloc need before allocated pointer. */ - mstat[type].t_realloc++; - - memory = zrealloc (type, ptr, size); - - mtype_log ("xrealloc", memory, file, line, type); - - return memory; -} - -/* Important function. */ -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); -} - -char * -mtype_zstrdup (const char *file, int line, int type, const char *str) -{ - char *memory; - - mstat[type].c_strdup++; - - memory = zstrdup (type, str); - - mtype_log ("xstrdup", memory, file, line, type); - - return memory; -} -#else -static struct -{ - char *name; - long alloc; -} mstat [MTYPE_MAX]; -#endif /* MEMORY_LOG */ - -/* Increment allocation counter. */ -static void -alloc_inc (int type) +qrealloc (struct memtype *mt, void *ptr, size_t size) { - mstat[type].alloc++; + if (ptr) + mt_count_free (mt); + return mt_checkalloc (mt, ptr ? realloc (ptr, size) : malloc (size), size); } -/* Decrement allocation counter. */ -static void -alloc_dec (int type) +void * +qstrdup (struct memtype *mt, const char *str) { - mstat[type].alloc--; -} - -/* Looking up memory status from vty interface. */ -#include "vector.h" -#include "vty.h" -#include "command.h" - -static void -log_memstats(int pri) -{ - struct mlist *ml; - - for (ml = mlists; ml->list; ml++) - { - struct memory_list *m; - - zlog (NULL, pri, "Memory utilization in module %s:", ml->name); - for (m = ml->list; m->index >= 0; m++) - if (m->index && mstat[m->index].alloc) - zlog (NULL, pri, " %-30s: %10ld", m->format, mstat[m->index].alloc); - } + return mt_checkalloc (mt, strdup (str), strlen (str) + 1); } void -log_memstats_stderr (const char *prefix) +qfree (struct memtype *mt, void *ptr) { - struct mlist *ml; - struct memory_list *m; - int i; - int j = 0; - - for (ml = mlists; ml->list; ml++) - { - i = 0; - - for (m = ml->list; m->index >= 0; m++) - if (m->index && mstat[m->index].alloc) - { - if (!i) - fprintf (stderr, - "%s: memstats: Current memory utilization in module %s:\n", - prefix, - ml->name); - fprintf (stderr, - "%s: memstats: %-30s: %10ld%s\n", - prefix, - m->format, - mstat[m->index].alloc, - mstat[m->index].alloc < 0 ? " (REPORT THIS BUG!)" : ""); - i = j = 1; - } - } - - if (j) - fprintf (stderr, - "%s: memstats: NOTE: If configuration exists, utilization may be " - "expected.\n", - prefix); - else - fprintf (stderr, - "%s: memstats: No remaining tracked memory utilization.\n", - prefix); + if (ptr) + mt_count_free (mt); + free (ptr); } -static void -show_separator(struct vty *vty) +int +qmem_walk (qmem_walk_fn *func, void *arg) { - vty_out (vty, "-----------------------------\r\n"); -} + struct memgroup *mg; + struct memtype *mt; + int rv; -static int -show_memory_vty (struct vty *vty, struct memory_list *list) -{ - struct memory_list *m; - int needsep = 0; - - for (m = list; m->index >= 0; m++) - if (m->index == 0) - { - if (needsep) - { - show_separator (vty); - needsep = 0; - } - } - else if (mstat[m->index].alloc) - { - vty_out (vty, "%-30s: %10ld\r\n", m->format, mstat[m->index].alloc); - needsep = 1; - } - return needsep; -} - -#ifdef HAVE_MALLINFO -static int -show_memory_mallinfo (struct vty *vty) -{ - struct mallinfo minfo = mallinfo(); - char buf[MTYPE_MEMSTR_LEN]; - - vty_out (vty, "System allocator statistics:%s", VTY_NEWLINE); - vty_out (vty, " Total heap allocated: %s%s", - mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.arena), - VTY_NEWLINE); - vty_out (vty, " Holding block headers: %s%s", - mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.hblkhd), - VTY_NEWLINE); - vty_out (vty, " Used small blocks: %s%s", - mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.usmblks), - VTY_NEWLINE); - vty_out (vty, " Used ordinary blocks: %s%s", - mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.uordblks), - VTY_NEWLINE); - vty_out (vty, " Free small blocks: %s%s", - mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fsmblks), - VTY_NEWLINE); - vty_out (vty, " Free ordinary blocks: %s%s", - mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fordblks), - VTY_NEWLINE); - vty_out (vty, " Ordinary blocks: %ld%s", - (unsigned long)minfo.ordblks, - VTY_NEWLINE); - vty_out (vty, " Small blocks: %ld%s", - (unsigned long)minfo.smblks, - VTY_NEWLINE); - vty_out (vty, " Holding blocks: %ld%s", - (unsigned long)minfo.hblks, - VTY_NEWLINE); - vty_out (vty, "(see system documentation for 'mallinfo' for meaning)%s", - VTY_NEWLINE); - return 1; -} -#endif /* HAVE_MALLINFO */ - -DEFUN (show_memory, - show_memory_cmd, - "show memory", - "Show running system information\n" - "Memory statistics\n") -{ - struct mlist *ml; - int needsep = 0; - -#ifdef HAVE_MALLINFO - needsep = show_memory_mallinfo (vty); -#endif /* HAVE_MALLINFO */ - - for (ml = mlists; ml->list; ml++) + for (mg = mg_first; mg; mg = mg->next) { - if (needsep) - show_separator (vty); - needsep = show_memory_vty (vty, ml->list); + if ((rv = func (arg, mg, NULL))) + return rv; + for (mt = mg->types; mt; mt = mt->next) + if ((rv = func (arg, mg, mt))) + return rv; } - - return CMD_SUCCESS; + return 0; } -void -memory_init (void) +struct exit_dump_args { - install_element (RESTRICTED_NODE, &show_memory_cmd); - - install_element (VIEW_NODE, &show_memory_cmd); - - install_element (ENABLE_NODE, &show_memory_cmd); -} + const char *prefix; + int error; +}; -/* Stats querying from users */ -/* Return a pointer to a human friendly string describing - * the byte count passed in. E.g: - * "0 bytes", "2048 bytes", "110kB", "500MiB", "11GiB", etc. - * Up to 4 significant figures will be given. - * The pointer returned may be NULL (indicating an error) - * or point to the given buffer, or point to static storage. - */ -const char * -mtype_memstr (char *buf, size_t len, unsigned long bytes) +static int +qmem_exit_walker (void *arg, struct memgroup *mg, struct memtype *mt) { - unsigned int m, k; - - /* easy cases */ - if (!bytes) - return "0 bytes"; - if (bytes == 1) - return "1 byte"; - - /* - * When we pass the 2gb barrier mallinfo() can no longer report - * correct data so it just does something odd... - * Reporting like Terrabytes of data. Which makes users... - * edgy.. yes edgy that's the term for it. - * So let's just give up gracefully - */ - if (bytes > 0x7fffffff) - return "> 2GB"; + struct exit_dump_args *eda = arg; - m = bytes >> 20; - k = bytes >> 10; - - if (m > 10) + if (!mt) { - if (bytes & (1 << 19)) - m++; - snprintf (buf, len, "%d MiB", m); + fprintf (stderr, "%s: showing active allocations in memory group %s\n", + eda->prefix, mg->name); } - else if (k > 10) + else if (mt->n_alloc) { - if (bytes & (1 << 9)) - k++; - snprintf (buf, len, "%d KiB", k); + char size[32]; + eda->error++; + snprintf (size, sizeof (size), "%10zu", mt->size); + fprintf (stderr, "%s: %-30s: %6zu * %s\n", + eda->prefix, mt->name, mt->n_alloc, + mt->size == SIZE_VAR ? "(variably sized)" : size); } - else - snprintf (buf, len, "%ld bytes", bytes); - - return buf; + return 0; } -unsigned long -mtype_stats_alloc (int type) +void +log_memstats_stderr (const char *prefix) { - return mstat[type].alloc; + struct exit_dump_args eda = { .prefix = prefix, .error = 0 }; + qmem_walk (qmem_exit_walker, &eda); } diff --git a/lib/memory.h b/lib/memory.h index 501352993d..d287f229f7 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -1,96 +1,198 @@ -/* Memory management routine - Copyright (C) 1998 Kunihiro Ishiguro - -This file is part of GNU Zebra. - -GNU Zebra is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU Zebra is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Zebra; see the file COPYING. If not, write to the Free -Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef _ZEBRA_MEMORY_H -#define _ZEBRA_MEMORY_H +/* + * Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _QUAGGA_MEMORY_H +#define _QUAGGA_MEMORY_H + +#include <stdlib.h> #define array_size(ar) (sizeof(ar) / sizeof(ar[0])) -/* For pretty printing of memory allocate information. */ -struct memory_list +#define SIZE_VAR ~0UL +struct memtype { - int index; - const char *format; + struct memtype *next, **ref; + const char *name; + size_t n_alloc; + size_t size; }; -struct mlist { - struct memory_list *list; +struct memgroup +{ + struct memgroup *next, **ref; + struct memtype *types, **insert; const char *name; }; - -#include "lib/memtypes.h" - -extern struct mlist mlists[]; - -/* #define MEMORY_LOG */ -#ifdef MEMORY_LOG -#define XMALLOC(mtype, size) \ - mtype_zmalloc (__FILE__, __LINE__, (mtype), (size)) -#define XCALLOC(mtype, size) \ - mtype_zcalloc (__FILE__, __LINE__, (mtype), (size)) -#define XREALLOC(mtype, ptr, size) \ - mtype_zrealloc (__FILE__, __LINE__, (mtype), (ptr), (size)) -#define XFREE(mtype, ptr) \ - do { \ - mtype_zfree (__FILE__, __LINE__, (mtype), (ptr)); \ - ptr = NULL; } \ - while (0) -#define XSTRDUP(mtype, str) \ - mtype_zstrdup (__FILE__, __LINE__, (mtype), (str)) -#else -#define XMALLOC(mtype, size) zmalloc ((mtype), (size)) -#define XCALLOC(mtype, size) zzcalloc ((mtype), (size)) -#define XREALLOC(mtype, ptr, size) zrealloc ((mtype), (ptr), (size)) -#define XFREE(mtype, ptr) do { \ - zfree ((mtype), (ptr)); \ - ptr = NULL; } \ - while (0) -#define XSTRDUP(mtype, str) zstrdup ((mtype), (str)) -#endif /* MEMORY_LOG */ - -/* Prototypes of memory function. */ -extern void *zmalloc (int type, size_t size); -extern void *zzcalloc (int type, size_t size); -extern void *zrealloc (int type, void *ptr, size_t size); -extern void zfree (int type, void *ptr); -extern char *zstrdup (int type, const char *str); - -extern void *mtype_zmalloc (const char *file, int line, int type, size_t size); - -extern void *mtype_zcalloc (const char *file, int line, int type, size_t size); - -extern void *mtype_zrealloc (const char *file, int line, int type, void *ptr, - size_t size); - -extern void mtype_zfree (const char *file, int line, int type, - void *ptr); - -extern char *mtype_zstrdup (const char *file, int line, int type, - const char *str); -extern void memory_init (void); + +#if defined(__clang__) +# if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5) +# define _RET_NONNULL , returns_nonnull +# endif +# define _CONSTRUCTOR(x) constructor(x) +#elif defined(__GNUC__) +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) +# define _RET_NONNULL , returns_nonnull +# endif +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +# define _CONSTRUCTOR(x) constructor(x) +# define _DESTRUCTOR(x) destructor(x) +# define _ALLOC_SIZE(x) alloc_size(x) +# endif +#endif + +#ifdef __sun +/* Solaris doesn't do constructor priorities due to linker restrictions */ +# undef _CONSTRUCTOR +# undef _DESTRUCTOR +#endif + +#ifndef _RET_NONNULL +# define _RET_NONNULL +#endif +#ifndef _CONSTRUCTOR +# define _CONSTRUCTOR(x) constructor +#endif +#ifndef _DESTRUCTOR +# define _DESTRUCTOR(x) destructor +#endif +#ifndef _ALLOC_SIZE +# define _ALLOC_SIZE(x) +#endif + +/* macro usage: + * + * mydaemon.h + * DECLARE_MGROUP(MYDAEMON) + * DECLARE_MTYPE(MYDAEMON_COMMON) + * + * mydaemon.c + * DEFINE_MGROUP(MYDAEMON, "my daemon memory") + * DEFINE_MTYPE(MYDAEMON, MYDAEMON_COMMON, + * "this mtype is used in multiple files in mydaemon") + * foo = qmalloc (MTYPE_MYDAEMON_COMMON, sizeof (*foo)) + * + * mydaemon_io.c + * bar = qmalloc (MTYPE_MYDAEMON_COMMON, sizeof (*bar)) + * + * DEFINE_MTYPE_STATIC(MYDAEMON, MYDAEMON_IO, + * "this mtype is used only in this file") + * baz = qmalloc (MTYPE_MYDAEMON_IO, sizeof (*baz)) + * + * Note: Naming conventions (MGROUP_ and MTYPE_ prefixes are enforced + * by not having these as part of the macro arguments) + * Note: MTYPE_* are symbols to the compiler (of type struct memtype *), + * but MGROUP_* aren't. + */ + +#define DECLARE_MGROUP(name) \ + extern struct memgroup _mg_##name; +#define DEFINE_MGROUP(mname, desc) \ + struct memgroup _mg_##mname \ + __attribute__ ((section (".data.mgroups"))) = { \ + .name = desc, \ + .types = NULL, .next = NULL, .insert = NULL, .ref = NULL, \ + }; \ + static void _mginit_##mname (void) \ + __attribute__ ((_CONSTRUCTOR (1000))); \ + static void _mginit_##mname (void) \ + { extern struct memgroup **mg_insert; \ + _mg_##mname.ref = mg_insert; \ + *mg_insert = &_mg_##mname; \ + mg_insert = &_mg_##mname.next; } \ + static void _mgfini_##mname (void) \ + __attribute__ ((_DESTRUCTOR (1000))); \ + static void _mgfini_##mname (void) \ + { if (_mg_##mname.next) \ + _mg_##mname.next->ref = _mg_##mname.ref; \ + *_mg_##mname.ref = _mg_##mname.next; } + + +#define DECLARE_MTYPE(name) \ + extern struct memtype _mt_##name; \ + static struct memtype * const MTYPE_ ## name = &_mt_##name; + +#define DEFINE_MTYPE_ATTR(group, mname, attr, desc) \ + attr struct memtype _mt_##mname \ + __attribute__ ((section (".data.mtypes"))) = { \ + .name = desc, \ + .next = NULL, .n_alloc = 0, .size = 0, .ref = NULL, \ + }; \ + static void _mtinit_##mname (void) \ + __attribute__ ((_CONSTRUCTOR (1001))); \ + static void _mtinit_##mname (void) \ + { if (_mg_##group.insert == NULL) \ + _mg_##group.insert = &_mg_##group.types; \ + _mt_##mname.ref = _mg_##group.insert; \ + *_mg_##group.insert = &_mt_##mname; \ + _mg_##group.insert = &_mt_##mname.next; } \ + static void _mtfini_##mname (void) \ + __attribute__ ((_DESTRUCTOR (1001))); \ + static void _mtfini_##mname (void) \ + { if (_mt_##mname.next) \ + _mt_##mname.next->ref = _mt_##mname.ref; \ + *_mt_##mname.ref = _mt_##mname.next; } + +#define DEFINE_MTYPE(group, name, desc) \ + DEFINE_MTYPE_ATTR(group, name, , desc) +#define DEFINE_MTYPE_STATIC(group, name, desc) \ + DEFINE_MTYPE_ATTR(group, name, static, desc) \ + static struct memtype * const MTYPE_ ## name = &_mt_##name; + +DECLARE_MGROUP(LIB) +DECLARE_MTYPE(TMP) + + +extern void *qmalloc (struct memtype *mt, size_t size) + __attribute__ ((malloc, _ALLOC_SIZE(2), nonnull (1) _RET_NONNULL)); +extern void *qcalloc (struct memtype *mt, size_t size) + __attribute__ ((malloc, _ALLOC_SIZE(2), nonnull (1) _RET_NONNULL)); +extern void *qrealloc (struct memtype *mt, void *ptr, size_t size) + __attribute__ ((_ALLOC_SIZE(3), nonnull (1) _RET_NONNULL)); +extern void *qstrdup (struct memtype *mt, const char *str) + __attribute__ ((malloc, nonnull (1) _RET_NONNULL)); +extern void qfree (struct memtype *mt, void *ptr) + __attribute__ ((nonnull (1))); + +#define XMALLOC(mtype, size) qmalloc(mtype, size) +#define XCALLOC(mtype, size) qcalloc(mtype, size) +#define XREALLOC(mtype, ptr, size) qrealloc(mtype, ptr, size) +#define XSTRDUP(mtype, str) qstrdup(mtype, str) +#define XFREE(mtype, ptr) do { qfree(mtype, ptr); ptr = NULL; } \ + while (0) + +static inline size_t mtype_stats_alloc(struct memtype *mt) +{ + return mt->n_alloc; +} + +/* NB: calls are ordered by memgroup; and there is a call with mt == NULL for + * each memgroup (so that a header can be printed, and empty memgroups show) + * + * return value: 0: continue, !0: abort walk. qmem_walk will return the + * last value from qmem_walk_fn. */ +typedef int qmem_walk_fn (void *arg, struct memgroup *mg, struct memtype *mt); +extern int qmem_walk (qmem_walk_fn *func, void *arg); extern void log_memstats_stderr (const char *); -/* return number of allocations outstanding for the type */ -extern unsigned long mtype_stats_alloc (int); +extern void memory_oom (size_t size, const char *name); -/* Human friendly string for given byte count */ -#define MTYPE_MEMSTR_LEN 20 -extern const char *mtype_memstr (char *, size_t, unsigned long); -#endif /* _ZEBRA_MEMORY_H */ +#endif /* _QUAGGA_MEMORY_H */ diff --git a/lib/memory_vty.c b/lib/memory_vty.c new file mode 100644 index 0000000000..e4cb295cf0 --- /dev/null +++ b/lib/memory_vty.c @@ -0,0 +1,169 @@ +/* + * Memory management routine + * Copyright (C) 1998 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <zebra.h> +/* malloc.h is generally obsolete, however GNU Libc mallinfo wants it. */ +#if !defined(HAVE_STDLIB_H) || (defined(GNU_LINUX) && defined(HAVE_MALLINFO)) +#include <malloc.h> +#endif /* !HAVE_STDLIB_H || HAVE_MALLINFO */ + +#include "log.h" +#include "memory.h" +#include "memory_vty.h" + +/* Looking up memory status from vty interface. */ +#include "vector.h" +#include "vty.h" +#include "command.h" + +#ifdef HAVE_MALLINFO +static int +show_memory_mallinfo (struct vty *vty) +{ + struct mallinfo minfo = mallinfo(); + char buf[MTYPE_MEMSTR_LEN]; + + vty_out (vty, "System allocator statistics:%s", VTY_NEWLINE); + vty_out (vty, " Total heap allocated: %s%s", + mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.arena), + VTY_NEWLINE); + vty_out (vty, " Holding block headers: %s%s", + mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.hblkhd), + VTY_NEWLINE); + vty_out (vty, " Used small blocks: %s%s", + mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.usmblks), + VTY_NEWLINE); + vty_out (vty, " Used ordinary blocks: %s%s", + mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.uordblks), + VTY_NEWLINE); + vty_out (vty, " Free small blocks: %s%s", + mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fsmblks), + VTY_NEWLINE); + vty_out (vty, " Free ordinary blocks: %s%s", + mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fordblks), + VTY_NEWLINE); + vty_out (vty, " Ordinary blocks: %ld%s", + (unsigned long)minfo.ordblks, + VTY_NEWLINE); + vty_out (vty, " Small blocks: %ld%s", + (unsigned long)minfo.smblks, + VTY_NEWLINE); + vty_out (vty, " Holding blocks: %ld%s", + (unsigned long)minfo.hblks, + VTY_NEWLINE); + vty_out (vty, "(see system documentation for 'mallinfo' for meaning)%s", + VTY_NEWLINE); + return 1; +} +#endif /* HAVE_MALLINFO */ + +static int qmem_walker(void *arg, struct memgroup *mg, struct memtype *mt) +{ + struct vty *vty = arg; + if (!mt) + vty_out (vty, "--- qmem %s ---%s", mg->name, VTY_NEWLINE); + else { + char size[32]; + snprintf(size, sizeof(size), "%6zu", mt->size); + vty_out (vty, "%-30s: %10zu %s%s", + mt->name, mt->n_alloc, + mt->size == 0 ? "" : + mt->size == SIZE_VAR ? "(variably sized)" : + size, VTY_NEWLINE); + } + return 0; +} + + +DEFUN (show_memory, + show_memory_cmd, + "show memory", + "Show running system information\n" + "Memory statistics\n") +{ +#ifdef HAVE_MALLINFO + show_memory_mallinfo (vty); +#endif /* HAVE_MALLINFO */ + + qmem_walk(qmem_walker, vty); + return CMD_SUCCESS; +} + +void +memory_init (void) +{ + install_element (RESTRICTED_NODE, &show_memory_cmd); + + install_element (VIEW_NODE, &show_memory_cmd); + + install_element (ENABLE_NODE, &show_memory_cmd); +} + +/* Stats querying from users */ +/* Return a pointer to a human friendly string describing + * the byte count passed in. E.g: + * "0 bytes", "2048 bytes", "110kB", "500MiB", "11GiB", etc. + * Up to 4 significant figures will be given. + * The pointer returned may be NULL (indicating an error) + * or point to the given buffer, or point to static storage. + */ +const char * +mtype_memstr (char *buf, size_t len, unsigned long bytes) +{ + unsigned int m, k; + + /* easy cases */ + if (!bytes) + return "0 bytes"; + if (bytes == 1) + return "1 byte"; + + /* + * When we pass the 2gb barrier mallinfo() can no longer report + * correct data so it just does something odd... + * Reporting like Terrabytes of data. Which makes users... + * edgy.. yes edgy that's the term for it. + * So let's just give up gracefully + */ + if (bytes > 0x7fffffff) + return "> 2GB"; + + m = bytes >> 20; + k = bytes >> 10; + + if (m > 10) + { + if (bytes & (1 << 19)) + m++; + snprintf (buf, len, "%d MiB", m); + } + else if (k > 10) + { + if (bytes & (1 << 9)) + k++; + snprintf (buf, len, "%d KiB", k); + } + else + snprintf (buf, len, "%ld bytes", bytes); + + return buf; +} diff --git a/lib/memory_vty.h b/lib/memory_vty.h new file mode 100644 index 0000000000..565a75aa98 --- /dev/null +++ b/lib/memory_vty.h @@ -0,0 +1,31 @@ +/* Memory management routine + Copyright (C) 1998 Kunihiro Ishiguro + +This file is part of GNU Zebra. + +GNU Zebra is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +GNU Zebra is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Zebra; see the file COPYING. If not, write to the Free +Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +#ifndef _ZEBRA_MEMORY_VTY_H +#define _ZEBRA_MEMORY_VTY_H + +#include "memory.h" + +extern void memory_init (void); + +/* Human friendly string for given byte count */ +#define MTYPE_MEMSTR_LEN 20 +extern const char *mtype_memstr (char *, size_t, unsigned long); +#endif /* _ZEBRA_MEMORY_VTY_H */ diff --git a/lib/memtypes.awk b/lib/memtypes.awk deleted file mode 100644 index bd13327db5..0000000000 --- a/lib/memtypes.awk +++ /dev/null @@ -1,87 +0,0 @@ -### -# Copyright (C) Paul Jakma 2005 -# -# This file is part of Quagga. -# -# Quagga is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# Quagga is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Quagga; see the file COPYING. If not, write to the Free -# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. -### -# -# Scan a file of memory definitions (see eg memtypes.c) and generate -# a corresponding header file with an enum of the MTYPE's and declarations -# for the struct memory_list arrays -# -# struct memory_list's must be declared as: -# '\nstruct memory_list memory_list_<name>[] .....' -# -# Each MTYPE_ within the definition must the second token on the line, -# tokens being delineated by whitespace. It may only consist of the set of -# characters [[:upper:]_[:digit:]]. Eg: -# -# '\n { MTYPE_AWESOME_IPV8 , "Amazing new protocol, says genius" {}..boo' -# -# We try to ignore lines whose first token is /* or *, ie C comment lines. -# So the following should work fine: -# -# '/* This is the best memory_list ever! -# ' * It's got all my MTYPE's */ -# ' -# 'struct memory_list memory_list_my_amazing_mlist[] = = -# '{ -# ' { MTYPE_DONGLE, "Dongle widget" } -# ' { MTYPE_FROB, "Frobulator" }, -# '{ MTYPE_WIPPLE, "Wipple combombulator"} -# '}}} -# -# Even if it isn't quite a valid C declaration. -# - -BEGIN { - mlistregex = "memory_list_(.*)\\[\\]"; - mtyperegex = "^(MTYPE_[[:upper:]_[:digit:]]+).*"; - header = "/* Auto-generated from memtypes.c by " ARGV[0] ". */\n"; - header = header "/* Do not edit! */\n"; - header = header "\n#ifndef _QUAGGA_MEMTYPES_H\n"; - header = header "#define _QUAGGA_MEMTYPES_H\n"; - footer = "\n#endif /* _QUAGGA_MEMTYPES_H */\n\n"; - mlistformat = "extern struct memory_list memory_list_%s[];"; - printf ("%s\n", header); -} - -# catch lines beginning with 'struct memory list ' and try snag the -# memory_list name. Has to be 3rd field. -($0 ~ /^struct memory_list /) && (NF >= 3) { - mlists[lcount++] = gensub(mlistregex, "\\1", "g",$3); -} - -# snag the MTYPE, it must self-standing and the second field, -# though we do manage to tolerate the , C seperator being appended -($1 !~ /^\/?\*/) && ($2 ~ /^MTYPE_/) { - mtype[tcount++] = gensub(mtyperegex, "\\1", "g", $2); -} - -END { - printf("enum\n{\n MTYPE_TMP = 1,\n"); - for (i = 0; i < tcount; i++) { - if (mtype[i] != "" && mtype[i] != "MTYPE_TMP") - printf (" %s,\n", mtype[i]); - } - printf (" MTYPE_MAX,\n};\n\n"); - for (i = 0; i < lcount; i++) { - if (mlists[i] != "") - printf (mlistformat "\n", mlists[i]); - } - printf (footer); -} diff --git a/lib/memtypes.c b/lib/memtypes.c deleted file mode 100644 index 510312f336..0000000000 --- a/lib/memtypes.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Memory type definitions. This file is parsed by memtypes.awk to extract - * MTYPE_ and memory_list_.. information in order to autogenerate - * memtypes.h. - * - * The script is sensitive to the format (though not whitespace), see - * the top of memtypes.awk for more details. - */ - -#include "zebra.h" -#include "memory.h" - -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_VTY, "VTY" }, - { MTYPE_VTY_OUT_BUF, "VTY output buffer" }, - { MTYPE_VTY_HIST, "VTY history" }, - { MTYPE_IF, "Interface" }, - { MTYPE_CONNECTED, "Connected" }, - { MTYPE_NBR_CONNECTED, "Neighbor Connected" }, - { MTYPE_CONNECTED_LABEL, "Connected interface label" }, - { 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_DISTRIBUTE_NAME, "Dist-list name" }, - { 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_PREFIX_LIST_TRIE, "Prefix List Trie Table" }, - { 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_ROUTE_MAP_DEP, "Route map dependency" }, - { MTYPE_CMD_TOKENS, "Command desc" }, - { MTYPE_KEY, "Key" }, - { MTYPE_KEYCHAIN, "Key chain" }, - { MTYPE_IF_RMAP, "Interface route map" }, - { MTYPE_IF_RMAP_NAME, "I.f. route map name", }, - { 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_PQUEUE, "Priority queue" }, - { MTYPE_PQUEUE_DATA, "Priority queue data" }, - { MTYPE_HOST, "Host config" }, - { MTYPE_BFD_INFO, "BFD info" }, - { MTYPE_VRF, "VRF" }, - { MTYPE_VRF_NAME, "VRF name" }, - { MTYPE_VRF_BITMAP, "VRF bit-map" }, - { MTYPE_NS, "Logical-Router" }, - { MTYPE_NS_NAME, "Logical-Router Name" }, - { MTYPE_NS_BITMAP, "Logical-Router bit-map" }, - { MTYPE_IF_LINK_PARAMS, "Informational Link Parameters" }, - { -1, NULL }, -}; - -struct memory_list memory_list_zebra[] = -{ - { MTYPE_RTADV_PREFIX, "Router Advertisement Prefix" }, - { MTYPE_ZEBRA_NS, "Zebra Name Space" }, - { MTYPE_ZEBRA_VRF, "ZEBRA VRF" }, - { MTYPE_NEXTHOP, "Nexthop" }, - { MTYPE_RIB, "RIB" }, - { MTYPE_RIB_QUEUE, "RIB process work queue" }, - { MTYPE_STATIC_ROUTE, "Static route" }, - { MTYPE_RIB_DEST, "RIB destination" }, - { MTYPE_RIB_TABLE_INFO, "RIB table info" }, - { MTYPE_RNH, "Nexthop tracking object" }, - { MTYPE_NETLINK_NAME, "Netlink name" }, - { -1, NULL }, -}; - -struct memory_list memory_list_bgp[] = -{ - { MTYPE_BGP, "BGP instance" }, - { MTYPE_BGP_LISTENER, "BGP listen socket details" }, - { MTYPE_BGP_PEER, "BGP peer" }, - { MTYPE_BGP_PEER_HOST, "BGP peer hostname" }, - { MTYPE_BGP_PEER_IFNAME, "BGP peer ifname" }, - { MTYPE_BGP_PEER_GROUP, "BGP Peer group" }, - { MTYPE_BGP_PEER_GROUP_HOST, "BGP Peer group hostname" }, - { MTYPE_PEER_DESC, "Peer description" }, - { MTYPE_PEER_PASSWORD, "Peer password string" }, - { MTYPE_BGP_PEER_AF, "BGP peer af" }, - { MTYPE_BGP_UPDGRP, "BGP update group" }, - { MTYPE_BGP_UPD_SUBGRP, "BGP update subgroup" }, - { MTYPE_BGP_PACKET, "BGP packet" }, - { MTYPE_ATTR, "BGP attribute" }, - { MTYPE_ATTR_EXTRA, "BGP extra attributes" }, - { 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_ROUTE_EXTRA, "BGP ancillary route info" }, - { MTYPE_BGP_CONN, "BGP connected" }, - { MTYPE_BGP_STATIC, "BGP static" }, - { MTYPE_BGP_ADVERTISE_ATTR, "BGP adv attr" }, - { MTYPE_BGP_ADVERTISE, "BGP adv" }, - { MTYPE_BGP_SYNCHRONISE, "BGP synchronise" }, - { MTYPE_BGP_ADJ_IN, "BGP adj in" }, - { MTYPE_BGP_ADJ_OUT, "BGP adj out" }, - { MTYPE_BGP_MPATH_INFO, "BGP multipath info" }, - { 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_DEBUG_FILTER, "BGP debug filter" }, - { MTYPE_BGP_DEBUG_STR, "BGP debug filter string" }, - { 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_PEER_CONF_IF, "BGP peer config 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_ADDR, "BGP own address" }, - { 0 , NULL}, - { MTYPE_BGP_REDIST, "BGP redistribution" }, - { MTYPE_BGP_FILTER_NAME, "BGP Filter Information" }, - { MTYPE_BGP_DUMP_STR, "BGP Dump String Information" }, - { MTYPE_ENCAP_TLV, "ENCAP TLV", }, - { -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" }, - { -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" }, - { -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_VERTEX_PARENT, "OSPF vertex parent", }, - { 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_MPLS_TE, "OSPF MPLS parameters" }, - { MTYPE_OSPF_PCE_PARAMS, "OSPF PCE parameters" }, - { -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" }, - { -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_DICT, "ISIS dictionary" }, - { MTYPE_ISIS_DICT_NODE, "ISIS dictionary node" }, - { MTYPE_ISIS_MPLS_TE, "ISIS MPLS_TE parameters" }, - { -1, NULL }, -}; - -struct memory_list memory_list_pim[] = -{ - { MTYPE_PIM_CHANNEL_OIL, "PIM SSM (S,G) channel OIL" }, - { MTYPE_PIM_INTERFACE, "PIM interface" }, - { MTYPE_PIM_IGMP_JOIN, "PIM interface IGMP static join" }, - { MTYPE_PIM_IGMP_SOCKET, "PIM interface IGMP socket" }, - { MTYPE_PIM_IGMP_GROUP, "PIM interface IGMP group" }, - { MTYPE_PIM_IGMP_GROUP_SOURCE, "PIM interface IGMP source" }, - { MTYPE_PIM_NEIGHBOR, "PIM interface neighbor" }, - { MTYPE_PIM_IFCHANNEL, "PIM interface (S,G) state" }, - { MTYPE_PIM_UPSTREAM, "PIM upstream (S,G) state" }, - { MTYPE_PIM_SSMPINGD, "PIM sspimgd socket" }, - { MTYPE_PIM_STATIC_ROUTE, "PIM Static Route" }, - { MTYPE_PIM_BR, "PIM Bridge Router info" }, - { -1, NULL }, -}; - -struct memory_list memory_list_vtysh[] = -{ - { MTYPE_VTYSH_CONFIG, "Vtysh configuration", }, - { MTYPE_VTYSH_CONFIG_LINE, "Vtysh configuration line" }, - { -1, NULL }, -}; - -struct mlist mlists[] __attribute__ ((unused)) = { - { memory_list_lib, "LIB" }, - { memory_list_zebra, "ZEBRA" }, - { memory_list_rip, "RIP" }, - { memory_list_ripng, "RIPNG" }, - { memory_list_ospf, "OSPF" }, - { memory_list_ospf6, "OSPF6" }, - { memory_list_isis, "ISIS" }, - { memory_list_bgp, "BGP" }, - { memory_list_pim, "PIM" }, - { NULL, NULL}, -}; diff --git a/lib/nexthop.c b/lib/nexthop.c index 14486ea157..427f77f87a 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -33,6 +33,8 @@ #include "prefix.h" #include "nexthop.h" +DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop") + /* check if nexthops are same, non-recursive */ int nexthop_same_no_recurse (struct nexthop *next1, struct nexthop *next2) @@ -39,6 +39,9 @@ #include "command.h" #include "vty.h" +DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router") +DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name") +DEFINE_MTYPE_STATIC(LIB, NS_BITMAP, "Logical-Router bit-map") #ifndef CLONE_NEWNET #define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */ diff --git a/lib/plist.c b/lib/plist.c index 7bb80fa2a4..eedb830c1a 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -34,6 +34,11 @@ #include "plist_int.h" +DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST, "Prefix List") +DEFINE_MTYPE_STATIC(LIB, MPREFIX_LIST_STR, "Prefix List Str") +DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST_ENTRY, "Prefix List Entry") +DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST_TRIE, "Prefix List Trie Table") + /* not currently changeable, code assumes bytes further down */ #define PLC_BITS 8 #define PLC_LEN (1 << PLC_BITS) @@ -236,7 +241,7 @@ prefix_list_insert (afi_t afi, int orf, const char *name) /* Allocate new prefix_list and copy given name. */ plist = prefix_list_new (); - plist->name = XSTRDUP (MTYPE_PREFIX_LIST_STR, name); + plist->name = XSTRDUP (MTYPE_MPREFIX_LIST_STR, name); plist->master = master; plist->trie = XCALLOC (MTYPE_PREFIX_LIST_TRIE, sizeof (struct pltrie_table)); @@ -370,7 +375,7 @@ prefix_list_delete (struct prefix_list *plist) (*master->delete_hook) (plist); if (plist->name) - XFREE (MTYPE_PREFIX_LIST_STR, plist->name); + XFREE (MTYPE_MPREFIX_LIST_STR, plist->name); XFREE (MTYPE_PREFIX_LIST_TRIE, plist->trie); diff --git a/lib/pqueue.c b/lib/pqueue.c index 69ab8e65d6..0f870564da 100644 --- a/lib/pqueue.c +++ b/lib/pqueue.c @@ -23,6 +23,9 @@ Boston, MA 02111-1307, USA. */ #include "memory.h" #include "pqueue.h" +DEFINE_MTYPE_STATIC(LIB, PQUEUE, "Priority queue") +DEFINE_MTYPE_STATIC(LIB, PQUEUE_DATA, "Priority queue data") + /* priority queue using heap sort */ /* pqueue->cmp() controls the order of sorting (i.e, ascending or diff --git a/lib/prefix.c b/lib/prefix.c index d2bb028315..34bb1a493a 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -28,6 +28,8 @@ #include "memory.h" #include "log.h" +DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix") + /* Maskbit. */ static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; diff --git a/lib/privs.c b/lib/privs.c index 3fb96aed12..9228a56d35 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -27,6 +27,9 @@ #include "memory.h" #ifdef HAVE_CAPABILITIES + +DEFINE_MTYPE_STATIC(LIB, PRIVS, "Privilege information") + /* sort out some generic internal types for: * * privilege values (cap_value_t, priv_t) -> pvalue_t diff --git a/lib/routemap.c b/lib/routemap.c index 9267056df6..10e5ed304c 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -30,6 +30,14 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "log.h" #include "hash.h" +DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP, "Route map") +DEFINE_MTYPE( LIB, ROUTE_MAP_NAME, "Route map name") +DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_INDEX, "Route map index") +DEFINE_MTYPE( LIB, ROUTE_MAP_RULE, "Route map rule") +DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_RULE_STR, "Route map rule str") +DEFINE_MTYPE( LIB, ROUTE_MAP_COMPILED, "Route map compiled") +DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_DEP, "Route map dependency") + /* Vector for route match rules. */ static vector route_match_vec; diff --git a/lib/routemap.h b/lib/routemap.h index f5981a87f3..7006e43f66 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -23,6 +23,10 @@ #define _ZEBRA_ROUTEMAP_H #include "prefix.h" +#include "memory.h" +DECLARE_MTYPE(ROUTE_MAP_NAME) +DECLARE_MTYPE(ROUTE_MAP_RULE) +DECLARE_MTYPE(ROUTE_MAP_COMPILED) /* Route map's type. */ enum route_map_type diff --git a/lib/sockunion.c b/lib/sockunion.c index 9184e500fc..96408965ab 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -29,6 +29,8 @@ #include "log.h" #include "jhash.h" +DEFINE_MTYPE_STATIC(LIB, SOCKUNION, "Socket union") + #ifndef HAVE_INET_ATON int inet_aton (const char *cp, struct in_addr *inaddr) diff --git a/lib/stream.c b/lib/stream.c index 809e749fb9..301ebc6275 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -29,6 +29,10 @@ #include "prefix.h" #include "log.h" +DEFINE_MTYPE_STATIC(LIB, STREAM, "Stream") +DEFINE_MTYPE_STATIC(LIB, STREAM_DATA, "Stream data") +DEFINE_MTYPE_STATIC(LIB, STREAM_FIFO, "Stream FIFO") + /* Tests whether a position is valid */ #define GETP_VALID(S,G) \ ((G) <= (S)->endp) diff --git a/lib/table.c b/lib/table.c index da21361684..8858aea0fd 100644 --- a/lib/table.c +++ b/lib/table.c @@ -27,6 +27,9 @@ #include "memory.h" #include "sockunion.h" +DEFINE_MTYPE( LIB, ROUTE_TABLE, "Route table") +DEFINE_MTYPE_STATIC(LIB, ROUTE_NODE, "Route node") + static void route_node_delete (struct route_node *); static void route_table_free (struct route_table *); diff --git a/lib/table.h b/lib/table.h index 2ffd79b53f..34c196aa47 100644 --- a/lib/table.h +++ b/lib/table.h @@ -23,6 +23,9 @@ #ifndef _ZEBRA_TABLE_H #define _ZEBRA_TABLE_H +#include "memory.h" +DECLARE_MTYPE(ROUTE_TABLE) + /* * Forward declarations. */ diff --git a/lib/thread.c b/lib/thread.c index a128786c3d..a26eb6bfd2 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -32,6 +32,10 @@ #include "command.h" #include "sigevent.h" +DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread") +DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master") +DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats") + #if defined(__APPLE__) #include <mach/mach.h> #include <mach/mach_time.h> @@ -287,13 +291,13 @@ cpu_record_print(struct vty *vty, thread_type filter) vty_out_cpu_thread_history(vty, &tmp); } -DEFUN(show_thread_cpu, - show_thread_cpu_cmd, - "show thread cpu [FILTER]", - SHOW_STR - "Thread information\n" - "Thread CPU usage\n" - "Display filter (rwtexb)\n") +DEFUN (show_thread_cpu, + show_thread_cpu_cmd, + "show thread cpu [FILTER]", + SHOW_STR + "Thread information\n" + "Thread CPU usage\n" + "Display filter (rwtexb)\n") { int i = 0; thread_type filter = (thread_type) -1U; @@ -369,13 +373,13 @@ cpu_record_clear (thread_type filter) tmp); } -DEFUN(clear_thread_cpu, - clear_thread_cpu_cmd, - "clear thread cpu [FILTER]", - "Clear stored data\n" - "Thread information\n" - "Thread CPU usage\n" - "Display filter (rwtexb)\n") +DEFUN (clear_thread_cpu, + clear_thread_cpu_cmd, + "clear thread cpu [FILTER]", + "Clear stored data\n" + "Thread information\n" + "Thread CPU usage\n" + "Display filter (rwtexb)\n") { int i = 0; thread_type filter = (thread_type) -1U; diff --git a/lib/vector.c b/lib/vector.c index 7c1486285f..03ad3171d6 100644 --- a/lib/vector.c +++ b/lib/vector.c @@ -24,6 +24,9 @@ #include "vector.h" #include "memory.h" +DEFINE_MTYPE_STATIC(LIB, VECTOR, "Vector") +DEFINE_MTYPE( LIB, VECTOR_INDEX, "Vector index") + /* Initialize vector : allocate memory and return vector. */ vector vector_init (unsigned int size) diff --git a/lib/vector.h b/lib/vector.h index 6b27fd96d4..d8f4c78608 100644 --- a/lib/vector.h +++ b/lib/vector.h @@ -23,6 +23,9 @@ #ifndef _ZEBRA_VECTOR_H #define _ZEBRA_VECTOR_H +#include "memory.h" +DECLARE_MTYPE(VECTOR_INDEX) + /* struct for vector */ struct _vector { @@ -30,6 +30,9 @@ #include "memory.h" #include "command.h" +DEFINE_MTYPE_STATIC(LIB, VRF, "VRF") +DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map") + /* * Turn on/off debug code * for vrf. @@ -40,6 +40,10 @@ #include <arpa/telnet.h> #include <termios.h> +DEFINE_MTYPE_STATIC(LIB, VTY, "VTY") +DEFINE_MTYPE_STATIC(LIB, VTY_OUT_BUF, "VTY output buffer") +DEFINE_MTYPE_STATIC(LIB, VTY_HIST, "VTY history") + /* Vty events */ enum event { diff --git a/lib/workqueue.c b/lib/workqueue.c index d351beb124..549bb2360a 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -29,6 +29,10 @@ #include "command.h" #include "log.h" +DEFINE_MTYPE(LIB, WORK_QUEUE, "Work queue") +DEFINE_MTYPE_STATIC(LIB, WORK_QUEUE_ITEM, "Work queue item") +DEFINE_MTYPE_STATIC(LIB, WORK_QUEUE_NAME, "Work queue name string") + /* master list of work_queues */ static struct list _work_queues; /* pointer primarily to avoid an otherwise harmless warning on @@ -178,11 +182,11 @@ work_queue_item_requeue (struct work_queue *wq, struct listnode *ln) LISTNODE_ATTACH (wq->items, ln); /* attach to end of list */ } -DEFUN(show_work_queues, - show_work_queues_cmd, - "show work-queues", - SHOW_STR - "Work Queue information\n") +DEFUN (show_work_queues, + show_work_queues_cmd, + "show work-queues", + SHOW_STR + "Work Queue information\n") { struct listnode *node; struct work_queue *wq; diff --git a/lib/workqueue.h b/lib/workqueue.h index 19b44041d7..eaf8574907 100644 --- a/lib/workqueue.h +++ b/lib/workqueue.h @@ -24,6 +24,9 @@ #ifndef _QUAGGA_WORK_QUEUE_H #define _QUAGGA_WORK_QUEUE_H +#include "memory.h" +DECLARE_MTYPE(WORK_QUEUE) + /* Hold time for the initial schedule of a queue run, in millisec */ #define WORK_QUEUE_DEFAULT_HOLD 50 diff --git a/lib/zclient.c b/lib/zclient.c index 753954fd84..057fa77580 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -34,6 +34,8 @@ #include "table.h" #include "nexthop.h" +DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient") + /* Zebra client events. */ enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT}; diff --git a/lib/zebra.h b/lib/zebra.h index fdfd471825..d7a441c2e9 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -318,26 +318,6 @@ struct in_pktinfo #endif /* - * OSPF Fragmentation / fragmented writes - * - * ospfd can support writing fragmented packets, for cases where - * kernel will not fragment IP_HDRINCL and/or multicast destined - * packets (ie TTBOMK all kernels, BSD, SunOS, Linux). However, - * SunOS, probably BSD too, clobber the user supplied IP ID and IP - * flags fields, hence user-space fragmentation will not work. - * Only Linux is known to leave IP header unmolested. - * Further, fragmentation really should be done the kernel, which already - * supports it, and which avoids nasty IP ID state problems. - * - * Fragmentation of OSPF packets can be required on networks with router - * with many many interfaces active in one area, or on networks with links - * with low MTUs. - */ -#ifdef GNU_LINUX -#define WANT_OSPF_WRITE_FRAGMENT -#endif - -/* * IP_HDRINCL / struct ip byte order * * Linux: network byte order @@ -396,57 +376,53 @@ struct in_pktinfo #define ZEBRA_PORT 2600 /* Zebra message types. */ -#define ZEBRA_INTERFACE_ADD 1 -#define ZEBRA_INTERFACE_DELETE 2 -#define ZEBRA_INTERFACE_ADDRESS_ADD 3 -#define ZEBRA_INTERFACE_ADDRESS_DELETE 4 -#define ZEBRA_INTERFACE_UP 5 -#define ZEBRA_INTERFACE_DOWN 6 -#define ZEBRA_IPV4_ROUTE_ADD 7 -#define ZEBRA_IPV4_ROUTE_DELETE 8 -#define ZEBRA_IPV6_ROUTE_ADD 9 -#define ZEBRA_IPV6_ROUTE_DELETE 10 -#define ZEBRA_REDISTRIBUTE_ADD 11 -#define ZEBRA_REDISTRIBUTE_DELETE 12 -#define ZEBRA_REDISTRIBUTE_DEFAULT_ADD 13 -#define ZEBRA_REDISTRIBUTE_DEFAULT_DELETE 14 -#define ZEBRA_IPV4_NEXTHOP_LOOKUP 15 -#define ZEBRA_IPV6_NEXTHOP_LOOKUP 16 -#define ZEBRA_IPV4_IMPORT_LOOKUP 17 -#define ZEBRA_IPV6_IMPORT_LOOKUP 18 -#define ZEBRA_INTERFACE_RENAME 19 -#define ZEBRA_ROUTER_ID_ADD 20 -#define ZEBRA_ROUTER_ID_DELETE 21 -#define ZEBRA_ROUTER_ID_UPDATE 22 -#define ZEBRA_HELLO 23 -#define ZEBRA_NEXTHOP_REGISTER 24 -#define ZEBRA_NEXTHOP_UNREGISTER 25 -#define ZEBRA_NEXTHOP_UPDATE 26 -#define ZEBRA_INTERFACE_NBR_ADDRESS_ADD 27 -#define ZEBRA_INTERFACE_NBR_ADDRESS_DELETE 28 -#define ZEBRA_INTERFACE_BFD_DEST_UPDATE 29 -#define ZEBRA_IMPORT_ROUTE_REGISTER 30 -#define ZEBRA_IMPORT_ROUTE_UNREGISTER 31 -#define ZEBRA_IMPORT_CHECK_UPDATE 32 -#define ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD 33 -#define ZEBRA_BFD_DEST_REGISTER 34 -#define ZEBRA_BFD_DEST_DEREGISTER 35 -#define ZEBRA_BFD_DEST_UPDATE 36 -#define ZEBRA_BFD_DEST_REPLAY 37 -#define ZEBRA_REDISTRIBUTE_IPV4_ADD 38 -#define ZEBRA_REDISTRIBUTE_IPV4_DEL 39 -#define ZEBRA_REDISTRIBUTE_IPV6_ADD 40 -#define ZEBRA_REDISTRIBUTE_IPV6_DEL 41 -#define ZEBRA_VRF_UNREGISTER 42 -#define ZEBRA_VRF_ADD 43 -#define ZEBRA_VRF_DELETE 44 -#define ZEBRA_INTERFACE_VRF_UPDATE 45 -#define ZEBRA_BFD_CLIENT_REGISTER 46 -#define ZEBRA_INTERFACE_ENABLE_RADV 47 -#define ZEBRA_INTERFACE_DISABLE_RADV 48 -#define ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB 49 -#define ZEBRA_INTERFACE_LINK_PARAMS 50 -#define ZEBRA_MESSAGE_MAX 51 +typedef enum { + ZEBRA_INTERFACE_ADD, + ZEBRA_INTERFACE_DELETE, + ZEBRA_INTERFACE_ADDRESS_ADD, + ZEBRA_INTERFACE_ADDRESS_DELETE, + ZEBRA_INTERFACE_UP, + ZEBRA_INTERFACE_DOWN, + ZEBRA_IPV4_ROUTE_ADD, + ZEBRA_IPV4_ROUTE_DELETE, + ZEBRA_IPV6_ROUTE_ADD, + ZEBRA_IPV6_ROUTE_DELETE, + ZEBRA_REDISTRIBUTE_ADD, + ZEBRA_REDISTRIBUTE_DELETE, + ZEBRA_REDISTRIBUTE_DEFAULT_ADD, + ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, + ZEBRA_ROUTER_ID_ADD, + ZEBRA_ROUTER_ID_DELETE, + ZEBRA_ROUTER_ID_UPDATE, + ZEBRA_HELLO, + ZEBRA_NEXTHOP_REGISTER, + ZEBRA_NEXTHOP_UNREGISTER, + ZEBRA_NEXTHOP_UPDATE, + ZEBRA_INTERFACE_NBR_ADDRESS_ADD, + ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, + ZEBRA_INTERFACE_BFD_DEST_UPDATE, + ZEBRA_IMPORT_ROUTE_REGISTER, + ZEBRA_IMPORT_ROUTE_UNREGISTER, + ZEBRA_IMPORT_CHECK_UPDATE, + ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD, + ZEBRA_BFD_DEST_REGISTER, + ZEBRA_BFD_DEST_DEREGISTER, + ZEBRA_BFD_DEST_UPDATE, + ZEBRA_BFD_DEST_REPLAY, + ZEBRA_REDISTRIBUTE_IPV4_ADD, + ZEBRA_REDISTRIBUTE_IPV4_DEL, + ZEBRA_REDISTRIBUTE_IPV6_ADD, + ZEBRA_REDISTRIBUTE_IPV6_DEL, + ZEBRA_VRF_UNREGISTER, + ZEBRA_VRF_ADD, + ZEBRA_VRF_DELETE, + ZEBRA_INTERFACE_VRF_UPDATE, + ZEBRA_BFD_CLIENT_REGISTER, + ZEBRA_INTERFACE_ENABLE_RADV, + ZEBRA_INTERFACE_DISABLE_RADV, + ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, + ZEBRA_INTERFACE_LINK_PARAMS, +} zebra_message_types_t; /* Marker value used in new Zserv, in the byte location corresponding * the command value in the old zserv header. To allow old and new @@ -542,43 +518,4 @@ typedef u_int16_t zebra_command_t; /* VRF ID type. */ typedef u_int16_t vrf_id_t; -/* FIFO -- first in first out structure and macros. */ -struct fifo -{ - struct fifo *next; - struct fifo *prev; -}; - -#define FIFO_INIT(F) \ - do { \ - struct fifo *Xfifo = (struct fifo *)(F); \ - Xfifo->next = Xfifo->prev = Xfifo; \ - } while (0) - -#define FIFO_ADD(F,N) \ - do { \ - struct fifo *Xfifo = (struct fifo *)(F); \ - struct fifo *Xnode = (struct fifo *)(N); \ - Xnode->next = Xfifo; \ - Xnode->prev = Xfifo->prev; \ - Xfifo->prev = Xfifo->prev->next = Xnode; \ - } while (0) - -#define FIFO_DEL(N) \ - do { \ - struct fifo *Xnode = (struct fifo *)(N); \ - Xnode->prev->next = Xnode->next; \ - Xnode->next->prev = Xnode->prev; \ - } while (0) - -#define FIFO_HEAD(F) \ - ((((struct fifo *)(F))->next == (struct fifo *)(F)) \ - ? NULL : (F)->next) - -#define FIFO_EMPTY(F) \ - (((struct fifo *)(F))->next == (struct fifo *)(F)) - -#define FIFO_TOP(F) \ - (FIFO_EMPTY(F) ? NULL : ((struct fifo *)(F))->next) - #endif /* _ZEBRA_H */ |
