mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 00:59:13 +00:00
commit
27c5d4de93
10
Makefile.am
10
Makefile.am
@ -5,7 +5,7 @@ include common.am
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib
|
||||
AM_CFLAGS = $(WERROR)
|
||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
|
||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE)
|
||||
LIBCAP = @LIBCAP@
|
||||
|
||||
EXTRA_DIST =
|
||||
@ -25,6 +25,14 @@ pkginclude_HEADERS =
|
||||
nodist_pkginclude_HEADERS =
|
||||
dist_examples_DATA =
|
||||
|
||||
## libtool, the self-made GNU scourge
|
||||
## ... this should fix relinking
|
||||
## ... and AUTOMAKE_DUMMY is needed to prevent automake from treating this
|
||||
## as overriding the normal targets...
|
||||
$(AUTOMAKE_DUMMY)install-moduleLTLIBRARIES: install-libLTLIBRARIES
|
||||
$(AUTOMAKE_DUMMY)install-binPROGRAMS: install-libLTLIBRARIES
|
||||
$(AUTOMAKE_DUMMY)install-sbinPROGRAMS: install-libLTLIBRARIES
|
||||
|
||||
include lib/subdir.am
|
||||
include zebra/subdir.am
|
||||
include qpb/subdir.am
|
||||
|
@ -219,9 +219,6 @@ static __attribute__((__noreturn__)) void bgp_exit(int status)
|
||||
memset(bm, 0, sizeof(*bm));
|
||||
|
||||
frr_fini();
|
||||
|
||||
if (bgp_debug_count())
|
||||
log_memstats_stderr("bgpd");
|
||||
exit(status);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include <zebra.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "prefix.h"
|
||||
#include "linklist.h"
|
||||
@ -9349,6 +9350,7 @@ static const char *table_stats_strs[] = {
|
||||
struct bgp_table_stats {
|
||||
struct bgp_table *table;
|
||||
unsigned long long counts[BGP_STATS_MAX];
|
||||
double total_space;
|
||||
};
|
||||
|
||||
#if 0
|
||||
@ -9417,8 +9419,8 @@ static int bgp_table_stats_walker(struct thread *t)
|
||||
ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
|
||||
/* announced address space */
|
||||
if (space)
|
||||
ts->counts[BGP_STATS_SPACE] +=
|
||||
1 << (space - rn->p.prefixlen);
|
||||
ts->total_space += pow(2.0,
|
||||
space - rn->p.prefixlen);
|
||||
} else if (prn->info)
|
||||
ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
|
||||
|
||||
@ -9528,31 +9530,26 @@ static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
|
||||
break;
|
||||
case BGP_STATS_SPACE:
|
||||
vty_out(vty, "%-30s: ", table_stats_strs[i]);
|
||||
vty_out(vty, "%12llu\n", ts.counts[i]);
|
||||
if (ts.counts[BGP_STATS_MAXBITLEN] < 9)
|
||||
break;
|
||||
vty_out(vty, "%30s: ", "%% announced ");
|
||||
vty_out(vty, "%12.2f\n",
|
||||
100 * (float)ts.counts[BGP_STATS_SPACE]
|
||||
/ (float)((uint64_t)1UL
|
||||
<< ts.counts
|
||||
[BGP_STATS_MAXBITLEN]));
|
||||
vty_out(vty, "%30s: ", "/8 equivalent ");
|
||||
vty_out(vty, "%12.2f\n",
|
||||
(float)ts.counts[BGP_STATS_SPACE]
|
||||
/ (float)(1UL
|
||||
<< (ts.counts
|
||||
[BGP_STATS_MAXBITLEN]
|
||||
- 8)));
|
||||
if (ts.counts[BGP_STATS_MAXBITLEN] < 25)
|
||||
break;
|
||||
vty_out(vty, "%30s: ", "/24 equivalent ");
|
||||
vty_out(vty, "%12.2f",
|
||||
(float)ts.counts[BGP_STATS_SPACE]
|
||||
/ (float)(1UL
|
||||
<< (ts.counts
|
||||
[BGP_STATS_MAXBITLEN]
|
||||
- 24)));
|
||||
vty_out(vty, "%12g\n", ts.total_space);
|
||||
|
||||
if (afi == AFI_IP6) {
|
||||
vty_out(vty, "%30s: ", "/32 equivalent ");
|
||||
vty_out(vty, "%12g\n",
|
||||
ts.total_space * pow(2.0, -128+32));
|
||||
vty_out(vty, "%30s: ", "/48 equivalent ");
|
||||
vty_out(vty, "%12g\n",
|
||||
ts.total_space * pow(2.0, -128+48));
|
||||
} else {
|
||||
vty_out(vty, "%30s: ", "% announced ");
|
||||
vty_out(vty, "%12.2f\n",
|
||||
ts.total_space * 100. * pow(2.0, -32));
|
||||
vty_out(vty, "%30s: ", "/8 equivalent ");
|
||||
vty_out(vty, "%12.2f\n",
|
||||
ts.total_space * pow(2.0, -32+8));
|
||||
vty_out(vty, "%30s: ", "/24 equivalent ");
|
||||
vty_out(vty, "%12.2f\n",
|
||||
ts.total_space * pow(2.0, -32+24));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vty_out(vty, "%-30s: ", table_stats_strs[i]);
|
||||
|
@ -13,8 +13,7 @@ CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py
|
||||
SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h
|
||||
.c_clippy.c:
|
||||
@{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; }
|
||||
$(AM_V_CLIPPY)$(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py $< > $@.tmp
|
||||
@{ test -f $@ && diff $@.tmp $@ >/dev/null 2>/dev/null; } && rm $@.tmp || mv $@.tmp $@
|
||||
$(AM_V_CLIPPY)$(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $<
|
||||
|
||||
## automake's "ylwrap" is a great piece of GNU software... not.
|
||||
.l.c:
|
||||
|
@ -11,14 +11,28 @@ def run(cmd):
|
||||
proc.wait()
|
||||
return rv
|
||||
|
||||
clangfmt = run(['git', 'show', 'master:.clang-format'])
|
||||
|
||||
argp = argparse.ArgumentParser(description = 'git whitespace-fixing tool')
|
||||
argp.add_argument('branch', metavar='BRANCH', type = str, nargs = '?', default = 'HEAD')
|
||||
args = argp.parse_args()
|
||||
|
||||
branch = args.branch
|
||||
commit = run(['git', 'rev-list', '-n', '1', branch, '--']).strip()
|
||||
beforeid = run(['git', 'rev-list', '-n', '1', 'reindent-master-before', '--']).strip()
|
||||
afterid = run(['git', 'rev-list', '-n', '1', 'reindent-master-after', '--']).strip()
|
||||
|
||||
# frr-3.1-dev = first commit that is on master but not on stable/3.0
|
||||
masterid = run(['git', 'rev-list', '-n', '1', 'frr-3.1-dev', '--']).strip()
|
||||
masterbase = run(['git', 'merge-base', commit, masterid]).strip()
|
||||
|
||||
if masterbase == masterid:
|
||||
refbranch = 'master'
|
||||
else:
|
||||
refbranch = '3.0'
|
||||
|
||||
sys.stderr.write('autodetected base: %s (can be 3.0 or master)\n' % refbranch)
|
||||
|
||||
beforeid = run(['git', 'rev-list', '-n', '1', 'reindent-%s-before' % refbranch, '--']).strip()
|
||||
afterid = run(['git', 'rev-list', '-n', '1', 'reindent-%s-after' % refbranch, '--']).strip()
|
||||
|
||||
beforebase = run(['git', 'merge-base', commit, beforeid]).strip()
|
||||
afterbase = run(['git', 'merge-base', commit, afterid]).strip()
|
||||
@ -28,10 +42,10 @@ if afterbase == afterid:
|
||||
sys.exit(1)
|
||||
|
||||
if beforebase != beforeid:
|
||||
sys.stderr.write('you need to rebase your branch onto the tag "reindent-master-before"\n')
|
||||
sys.stderr.write('you need to rebase your branch onto the tag "reindent-%s-before"\n' % refbranch)
|
||||
sys.exit(1)
|
||||
|
||||
revs = run(['git', 'rev-list', 'reindent-master-before..%s' % commit]).strip().split('\n')
|
||||
revs = run(['git', 'rev-list', 'reindent-%s-before..%s' % (refbranch, commit)]).strip().split('\n')
|
||||
revs.reverse()
|
||||
|
||||
srcdir = os.getcwd()
|
||||
@ -39,9 +53,12 @@ tmpdir = tempfile.mkdtemp('frrindent')
|
||||
os.chdir(tmpdir)
|
||||
|
||||
sys.stderr.write('using temporary directory %s; %d revisions\n' % (tmpdir, len(revs)))
|
||||
run(['git', 'clone', '-s', '-b', 'reindent-master-after', srcdir, 'repo'])
|
||||
run(['git', 'clone', '-s', '-b', 'reindent-%s-after' % refbranch, srcdir, 'repo'])
|
||||
os.chdir('repo')
|
||||
|
||||
with open('.clang-format', 'w') as fd:
|
||||
fd.write(clangfmt)
|
||||
|
||||
prev = beforeid
|
||||
for rev in revs:
|
||||
filestat = run(['git', 'diff', '-z', '--name-status', prev, rev]).rstrip('\0').split('\0')
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "command_graph.h"
|
||||
#include "qobj.h"
|
||||
#include "defaults.h"
|
||||
#include "libfrr.h"
|
||||
|
||||
DEFINE_MTYPE(LIB, HOST, "Host config")
|
||||
DEFINE_MTYPE(LIB, STRVEC, "String vector")
|
||||
@ -359,21 +360,23 @@ void install_element(enum node_type ntype, struct cmd_element *cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
cnode = vector_slot(cmdvec, ntype);
|
||||
cnode = vector_lookup(cmdvec, ntype);
|
||||
|
||||
if (cnode == NULL) {
|
||||
fprintf(stderr,
|
||||
"Command node %d doesn't exist, please check it\n",
|
||||
ntype);
|
||||
fprintf(stderr,
|
||||
"Have you called install_node before this install_element?\n");
|
||||
"%s[%s]:\n"
|
||||
"\tnode %d (%s) does not exist.\n"
|
||||
"\tplease call install_node() before install_element()\n",
|
||||
cmd->name, cmd->string, ntype, node_names[ntype]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (hash_lookup(cnode->cmd_hash, cmd) != NULL) {
|
||||
fprintf(stderr,
|
||||
"Multiple command installs to node %d of command:\n%s\n",
|
||||
ntype, cmd->string);
|
||||
"%s[%s]:\n"
|
||||
"\tnode %d (%s) already has this command installed.\n"
|
||||
"\tduplicate install_element call?\n",
|
||||
cmd->name, cmd->string, ntype, node_names[ntype]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -406,21 +409,23 @@ void uninstall_element(enum node_type ntype, struct cmd_element *cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
cnode = vector_slot(cmdvec, ntype);
|
||||
cnode = vector_lookup(cmdvec, ntype);
|
||||
|
||||
if (cnode == NULL) {
|
||||
fprintf(stderr,
|
||||
"Command node %d doesn't exist, please check it\n",
|
||||
ntype);
|
||||
fprintf(stderr,
|
||||
"Have you called install_node before this install_element?\n");
|
||||
"%s[%s]:\n"
|
||||
"\tnode %d (%s) does not exist.\n"
|
||||
"\tplease call install_node() before uninstall_element()\n",
|
||||
cmd->name, cmd->string, ntype, node_names[ntype]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (hash_release(cnode->cmd_hash, cmd) == NULL) {
|
||||
fprintf(stderr,
|
||||
"Trying to uninstall non-installed command (node %d):\n%s\n",
|
||||
ntype, cmd->string);
|
||||
"%s[%s]:\n"
|
||||
"\tnode %d (%s) does not have this command installed.\n"
|
||||
"\tduplicate uninstall_element call?\n",
|
||||
cmd->name, cmd->string, ntype, node_names[ntype]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -555,6 +560,9 @@ static int config_write_host(struct vty *vty)
|
||||
else if (!host.motd)
|
||||
vty_out(vty, "no banner motd\n");
|
||||
|
||||
if (debug_memstats_at_exit)
|
||||
vty_out(vty, "!\ndebug memstats-at-exit\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2366,6 +2374,17 @@ DEFUN (no_config_log_timestamp_precision,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (debug_memstats,
|
||||
debug_memstats_cmd,
|
||||
"[no] debug memstats-at-exit",
|
||||
NO_STR
|
||||
DEBUG_STR
|
||||
"Print memory type statistics at exit\n")
|
||||
{
|
||||
debug_memstats_at_exit = !!strcmp(argv[0]->text, "no");
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int cmd_banner_motd_file(const char *file)
|
||||
{
|
||||
int success = CMD_SUCCESS;
|
||||
@ -2527,6 +2546,7 @@ void cmd_init(int terminal)
|
||||
/* Each node's basic commands. */
|
||||
install_element(VIEW_NODE, &show_version_cmd);
|
||||
install_element(ENABLE_NODE, &show_startup_config_cmd);
|
||||
install_element(ENABLE_NODE, &debug_memstats_cmd);
|
||||
|
||||
if (terminal) {
|
||||
install_element(VIEW_NODE, &config_list_cmd);
|
||||
@ -2560,6 +2580,7 @@ void cmd_init(int terminal)
|
||||
install_element(CONFIG_NODE, &hostname_cmd);
|
||||
install_element(CONFIG_NODE, &no_hostname_cmd);
|
||||
install_element(CONFIG_NODE, &frr_version_defaults_cmd);
|
||||
install_element(CONFIG_NODE, &debug_memstats_cmd);
|
||||
|
||||
if (terminal > 0) {
|
||||
install_element(CONFIG_NODE, &password_cmd);
|
||||
|
81
lib/compiler.h
Normal file
81
lib/compiler.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2017 David Lamparter, for NetDEF, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _FRR_COMPILER_H
|
||||
#define _FRR_COMPILER_H
|
||||
|
||||
/* function attributes, use like
|
||||
* void prototype(void) __attribute__((_CONSTRUCTOR(100)));
|
||||
*/
|
||||
#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
|
||||
|
||||
/* fallback versions */
|
||||
#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
|
||||
|
||||
/*
|
||||
* for warnings on macros, put in the macro content like this:
|
||||
* #define MACRO BLA CPP_WARN("MACRO has been deprecated")
|
||||
*/
|
||||
#define CPP_STR(X) #X
|
||||
|
||||
#if defined(__ICC)
|
||||
#define CPP_NOTICE(text) _Pragma(CPP_STR(message __FILE__ ": " text))
|
||||
#define CPP_WARN(text) CPP_NOTICE(text)
|
||||
|
||||
#elif (defined(__GNUC__) \
|
||||
&& (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) \
|
||||
|| (defined(__clang__) \
|
||||
&& (__clang_major__ >= 4 \
|
||||
|| (__clang_major__ == 3 && __clang_minor__ >= 5)))
|
||||
#define CPP_WARN(text) _Pragma(CPP_STR(GCC warning text))
|
||||
#define CPP_NOTICE(text) _Pragma(CPP_STR(message text))
|
||||
|
||||
#else
|
||||
#define CPP_WARN(text)
|
||||
#endif
|
||||
|
||||
#endif /* _FRR_COMPILER_H */
|
@ -404,7 +404,8 @@ DEFUN (grammar_findambig,
|
||||
nodegraph = cnode->cmdgraph;
|
||||
if (!nodegraph)
|
||||
continue;
|
||||
vty_out(vty, "scanning node %d\n", scannode - 1);
|
||||
vty_out(vty, "scanning node %d (%s)\n",
|
||||
scannode - 1, node_names[scannode - 1]);
|
||||
}
|
||||
|
||||
commands = cmd_graph_permutations(nodegraph);
|
||||
|
35
lib/libfrr.c
35
lib/libfrr.c
@ -52,6 +52,8 @@ char frr_zclientpath[256];
|
||||
static char pidfile_default[256];
|
||||
static char vtypath_default[256];
|
||||
|
||||
bool debug_memstats_at_exit = 0;
|
||||
|
||||
static char comb_optstr[256];
|
||||
static struct option comb_lo[64];
|
||||
static struct option *comb_next_lo = &comb_lo[0];
|
||||
@ -639,7 +641,10 @@ static void frr_daemon_wait(int fd)
|
||||
exit(0);
|
||||
|
||||
/* child failed one way or another ... */
|
||||
if (WIFEXITED(exitstat))
|
||||
if (WIFEXITED(exitstat) && WEXITSTATUS(exitstat) == 0)
|
||||
/* can happen in --terminal case if exit is fast enough */
|
||||
(void)0;
|
||||
else if (WIFEXITED(exitstat))
|
||||
fprintf(stderr, "%s failed to start, exited %d\n", di->name,
|
||||
WEXITSTATUS(exitstat));
|
||||
else if (WIFSIGNALED(exitstat))
|
||||
@ -841,6 +846,10 @@ void frr_early_fini(void)
|
||||
|
||||
void frr_fini(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char filename[128];
|
||||
int have_leftovers;
|
||||
|
||||
hook_call(frr_fini);
|
||||
|
||||
/* memory_init -> nothing needed */
|
||||
@ -851,4 +860,28 @@ void frr_fini(void)
|
||||
thread_master_free(master);
|
||||
closezlog();
|
||||
/* frrmod_init -> nothing needed / hooks */
|
||||
|
||||
if (!debug_memstats_at_exit)
|
||||
return;
|
||||
|
||||
have_leftovers = log_memstats(stderr, di->name);
|
||||
|
||||
/* in case we decide at runtime that we want exit-memstats for
|
||||
* a daemon, but it has no stderr because it's daemonized
|
||||
* (only do this if we actually have something to print though)
|
||||
*/
|
||||
if (!have_leftovers)
|
||||
return;
|
||||
|
||||
snprintf(filename, sizeof(filename),
|
||||
"/tmp/frr-memstats-%s-%llu-%llu",
|
||||
di->name,
|
||||
(unsigned long long)getpid(),
|
||||
(unsigned long long)time(NULL));
|
||||
|
||||
fp = fopen(filename, "w");
|
||||
if (fp) {
|
||||
log_memstats(fp, di->name);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
@ -121,4 +121,6 @@ extern const char frr_moduledir[];
|
||||
extern char frr_protoname[];
|
||||
extern char frr_protonameinst[];
|
||||
|
||||
extern bool debug_memstats_at_exit;
|
||||
|
||||
#endif /* _ZEBRA_FRR_H */
|
||||
|
@ -701,7 +701,7 @@ void _zlog_assert_failed(const char *assertion, const char *file,
|
||||
assertion, file, line, (function ? function : "?"));
|
||||
zlog_backtrace(LOG_CRIT);
|
||||
zlog_thread_info(LOG_CRIT);
|
||||
log_memstats_stderr("log");
|
||||
log_memstats(stderr, "log");
|
||||
abort();
|
||||
}
|
||||
|
||||
|
10
lib/memory.c
10
lib/memory.c
@ -104,6 +104,7 @@ int qmem_walk(qmem_walk_fn *func, void *arg)
|
||||
}
|
||||
|
||||
struct exit_dump_args {
|
||||
FILE *fp;
|
||||
const char *prefix;
|
||||
int error;
|
||||
};
|
||||
@ -113,7 +114,7 @@ static int qmem_exit_walker(void *arg, struct memgroup *mg, struct memtype *mt)
|
||||
struct exit_dump_args *eda = arg;
|
||||
|
||||
if (!mt) {
|
||||
fprintf(stderr,
|
||||
fprintf(eda->fp,
|
||||
"%s: showing active allocations in "
|
||||
"memory group %s\n",
|
||||
eda->prefix, mg->name);
|
||||
@ -122,15 +123,16 @@ static int qmem_exit_walker(void *arg, struct memgroup *mg, struct memtype *mt)
|
||||
char size[32];
|
||||
eda->error++;
|
||||
snprintf(size, sizeof(size), "%10zu", mt->size);
|
||||
fprintf(stderr, "%s: memstats: %-30s: %6zu * %s\n",
|
||||
fprintf(eda->fp, "%s: memstats: %-30s: %6zu * %s\n",
|
||||
eda->prefix, mt->name, mt->n_alloc,
|
||||
mt->size == SIZE_VAR ? "(variably sized)" : size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void log_memstats_stderr(const char *prefix)
|
||||
int log_memstats(FILE *fp, const char *prefix)
|
||||
{
|
||||
struct exit_dump_args eda = {.prefix = prefix, .error = 0};
|
||||
struct exit_dump_args eda = { .fp = fp, .prefix = prefix, .error = 0 };
|
||||
qmem_walk(qmem_exit_walker, &eda);
|
||||
return eda.error;
|
||||
}
|
||||
|
40
lib/memory.h
40
lib/memory.h
@ -18,7 +18,9 @@
|
||||
#define _QUAGGA_MEMORY_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <frratomic.h>
|
||||
#include "compiler.h"
|
||||
|
||||
#define array_size(ar) (sizeof(ar) / sizeof(ar[0]))
|
||||
|
||||
@ -36,41 +38,6 @@ struct memgroup {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#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
|
||||
@ -194,7 +161,8 @@ static inline size_t mtype_stats_alloc(struct memtype *mt)
|
||||
* 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 *);
|
||||
extern int log_memstats(FILE *fp, const char *);
|
||||
#define log_memstats_stderr(prefix) log_memstats(stderr, prefix)
|
||||
|
||||
extern void memory_oom(size_t size, const char *name);
|
||||
|
||||
|
@ -122,6 +122,14 @@ const char *prefix_list_name(struct prefix_list *plist)
|
||||
return plist->name;
|
||||
}
|
||||
|
||||
afi_t prefix_list_afi(struct prefix_list *plist)
|
||||
{
|
||||
if (plist->master == &prefix_master_ipv4
|
||||
|| plist->master == &prefix_master_orf_v4)
|
||||
return AFI_IP;
|
||||
return AFI_IP6;
|
||||
}
|
||||
|
||||
/* Lookup prefix_list from list of prefix_list by name. */
|
||||
static struct prefix_list *prefix_list_lookup_do(afi_t afi, int orf,
|
||||
const char *name)
|
||||
|
@ -48,6 +48,7 @@ extern void prefix_list_add_hook(void (*func)(struct prefix_list *));
|
||||
extern void prefix_list_delete_hook(void (*func)(struct prefix_list *));
|
||||
|
||||
extern const char *prefix_list_name(struct prefix_list *);
|
||||
extern afi_t prefix_list_afi(struct prefix_list *);
|
||||
extern struct prefix_list *prefix_list_lookup(afi_t, const char *);
|
||||
extern enum prefix_list_type prefix_list_apply(struct prefix_list *, void *);
|
||||
|
||||
|
@ -1263,5 +1263,6 @@ unsigned prefix_hash_key(void *pp)
|
||||
* padding and unused prefix bytes. */
|
||||
memset(©, 0, sizeof(copy));
|
||||
prefix_copy(©, (struct prefix *)pp);
|
||||
return jhash(©, sizeof(copy), 0x55aa5a5a);
|
||||
return jhash(©, offsetof(struct prefix, u.prefix)
|
||||
+ PSIZE(copy.prefixlen), 0x55aa5a5a);
|
||||
}
|
||||
|
17
lib/prefix.h
17
lib/prefix.h
@ -33,28 +33,13 @@
|
||||
#endif
|
||||
#include "sockunion.h"
|
||||
#include "ipaddr.h"
|
||||
#include "compiler.h"
|
||||
|
||||
#ifndef ETH_ALEN
|
||||
#define ETH_ALEN 6
|
||||
#endif
|
||||
|
||||
/* for compatibility */
|
||||
#if defined(__ICC)
|
||||
#define CPP_WARN_STR(X) #X
|
||||
#define CPP_WARN(text) _Pragma(CPP_WARN_STR(message __FILE__ ": " text))
|
||||
|
||||
#elif (defined(__GNUC__) \
|
||||
&& (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) \
|
||||
|| (defined(__clang__) \
|
||||
&& (__clang_major__ >= 4 \
|
||||
|| (__clang_major__ == 3 && __clang_minor__ >= 5)))
|
||||
#define CPP_WARN_STR(X) #X
|
||||
#define CPP_WARN(text) _Pragma(CPP_WARN_STR(GCC warning text))
|
||||
|
||||
#else
|
||||
#define CPP_WARN(text)
|
||||
#endif
|
||||
|
||||
#ifdef ETHER_ADDR_LEN
|
||||
#undef ETHER_ADDR_LEN
|
||||
#endif
|
||||
|
@ -245,7 +245,7 @@ core_handler(int signo
|
||||
#endif
|
||||
);
|
||||
/* dump memory stats on core */
|
||||
log_memstats_stderr("core_handler");
|
||||
log_memstats(stderr, "core_handler");
|
||||
abort();
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,7 @@ pkginclude_HEADERS += \
|
||||
lib/command.h \
|
||||
lib/command_graph.h \
|
||||
lib/command_match.h \
|
||||
lib/compiler.h \
|
||||
lib/csv.h \
|
||||
lib/distribute.h \
|
||||
lib/event_counter.h \
|
||||
|
19
lib/vty.h
19
lib/vty.h
@ -25,6 +25,7 @@
|
||||
#include "log.h"
|
||||
#include "sockunion.h"
|
||||
#include "qobj.h"
|
||||
#include "compiler.h"
|
||||
|
||||
#define VTY_BUFSIZ 4096
|
||||
#define VTY_MAXHIST 20
|
||||
@ -182,23 +183,11 @@ struct vty_arg {
|
||||
/* Integrated configuration file. */
|
||||
#define INTEGRATE_DEFAULT_CONFIG "frr.conf"
|
||||
|
||||
/* for compatibility */
|
||||
#if defined(__ICC)
|
||||
#define CPP_WARN_STR(X) #X
|
||||
#define CPP_WARN(text) _Pragma(CPP_WARN_STR(message __FILE__ ": " text))
|
||||
|
||||
#elif (defined(__GNUC__) \
|
||||
&& (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) \
|
||||
|| (defined(__clang__) \
|
||||
&& (__clang_major__ >= 4 \
|
||||
|| (__clang_major__ == 3 && __clang_minor__ >= 5)))
|
||||
#define CPP_WARN_STR(X) #X
|
||||
#define CPP_WARN(text) _Pragma(CPP_WARN_STR(GCC warning text))
|
||||
|
||||
#else
|
||||
#define CPP_WARN(text)
|
||||
#if CONFDATE > 20180401
|
||||
CPP_NOTICE("It's probably time to remove VTY_NEWLINE compatibility foo.")
|
||||
#endif
|
||||
|
||||
/* for compatibility */
|
||||
#define VNL "\n" CPP_WARN("VNL has been replaced with \\n.")
|
||||
#define VTYNL "\n" CPP_WARN("VTYNL has been replaced with \\n.")
|
||||
#define VTY_NEWLINE "\n" CPP_WARN("VTY_NEWLINE has been replaced with \\n.")
|
||||
|
@ -386,27 +386,20 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
|
||||
}
|
||||
|
||||
/* Check filter-list */
|
||||
if (PREFIX_NAME_OUT(area)) {
|
||||
if (PREFIX_LIST_OUT(area) == NULL)
|
||||
PREFIX_LIST_OUT(area) = prefix_list_lookup(
|
||||
AFI_IP6, PREFIX_NAME_OUT(area));
|
||||
|
||||
if (PREFIX_LIST_OUT(area))
|
||||
if (prefix_list_apply(PREFIX_LIST_OUT(area),
|
||||
&route->prefix)
|
||||
!= PREFIX_PERMIT) {
|
||||
if (is_debug) {
|
||||
inet_ntop(AF_INET,
|
||||
&(ADV_ROUTER_IN_PREFIX(
|
||||
&route->prefix)),
|
||||
buf, sizeof(buf));
|
||||
zlog_debug(
|
||||
"prefix %s was denied by filter-list out",
|
||||
buf);
|
||||
}
|
||||
return 0;
|
||||
if (PREFIX_LIST_OUT(area))
|
||||
if (prefix_list_apply(PREFIX_LIST_OUT(area), &route->prefix)
|
||||
!= PREFIX_PERMIT) {
|
||||
if (is_debug) {
|
||||
inet_ntop(AF_INET,
|
||||
&(ADV_ROUTER_IN_PREFIX(
|
||||
&route->prefix)),
|
||||
buf, sizeof(buf));
|
||||
zlog_debug(
|
||||
"prefix %s was denied by filter-list out",
|
||||
buf);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the route is going to be originated. store it in area's summary_table
|
||||
*/
|
||||
@ -873,22 +866,16 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
|
||||
}
|
||||
|
||||
/* Check input prefix-list */
|
||||
if (PREFIX_NAME_IN(oa)) {
|
||||
if (PREFIX_LIST_IN(oa) == NULL)
|
||||
PREFIX_LIST_IN(oa) =
|
||||
prefix_list_lookup(AFI_IP6, PREFIX_NAME_IN(oa));
|
||||
|
||||
if (PREFIX_LIST_IN(oa))
|
||||
if (prefix_list_apply(PREFIX_LIST_IN(oa), &prefix)
|
||||
!= PREFIX_PERMIT) {
|
||||
if (is_debug)
|
||||
zlog_debug(
|
||||
"Prefix was denied by prefix-list");
|
||||
if (old)
|
||||
ospf6_route_remove(old, table);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (PREFIX_LIST_IN(oa))
|
||||
if (prefix_list_apply(PREFIX_LIST_IN(oa), &prefix)
|
||||
!= PREFIX_PERMIT) {
|
||||
if (is_debug)
|
||||
zlog_debug(
|
||||
"Prefix was denied by prefix-list");
|
||||
if (old)
|
||||
ospf6_route_remove(old, table);
|
||||
return;
|
||||
}
|
||||
|
||||
/* (5),(6): the path preference is handled by the sorting
|
||||
in the routing table. Always install the path by substituting
|
||||
|
@ -45,6 +45,8 @@
|
||||
#include "ospf6_asbr.h"
|
||||
#include "ospf6d.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name")
|
||||
|
||||
int ospf6_area_cmp(void *va, void *vb)
|
||||
{
|
||||
struct ospf6_area *oa = (struct ospf6_area *)va;
|
||||
@ -579,17 +581,15 @@ DEFUN (area_filter_list,
|
||||
plist = prefix_list_lookup(AFI_IP6, plistname);
|
||||
if (strmatch(inout, "in")) {
|
||||
PREFIX_LIST_IN(area) = plist;
|
||||
if (PREFIX_NAME_IN(area))
|
||||
free(PREFIX_NAME_IN(area));
|
||||
|
||||
PREFIX_NAME_IN(area) = strdup(plistname);
|
||||
XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area));
|
||||
PREFIX_NAME_IN(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME,
|
||||
plistname);
|
||||
ospf6_abr_reimport(area);
|
||||
} else {
|
||||
PREFIX_LIST_OUT(area) = plist;
|
||||
if (PREFIX_NAME_OUT(area))
|
||||
free(PREFIX_NAME_OUT(area));
|
||||
|
||||
PREFIX_NAME_OUT(area) = strdup(plistname);
|
||||
XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area));
|
||||
PREFIX_NAME_OUT(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME,
|
||||
plistname);
|
||||
ospf6_abr_enable_area(area);
|
||||
}
|
||||
|
||||
@ -622,27 +622,34 @@ DEFUN (no_area_filter_list,
|
||||
return CMD_SUCCESS;
|
||||
|
||||
PREFIX_LIST_IN(area) = NULL;
|
||||
if (PREFIX_NAME_IN(area))
|
||||
free(PREFIX_NAME_IN(area));
|
||||
|
||||
PREFIX_NAME_IN(area) = NULL;
|
||||
XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area));
|
||||
ospf6_abr_reimport(area);
|
||||
} else {
|
||||
if (PREFIX_NAME_OUT(area))
|
||||
if (!strmatch(PREFIX_NAME_OUT(area), plistname))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
PREFIX_LIST_OUT(area) = NULL;
|
||||
if (PREFIX_NAME_OUT(area))
|
||||
free(PREFIX_NAME_OUT(area));
|
||||
|
||||
PREFIX_NAME_OUT(area) = NULL;
|
||||
XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area));
|
||||
ospf6_abr_enable_area(area);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
void ospf6_area_plist_update(struct prefix_list *plist, int add)
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
struct listnode *n;
|
||||
const char *name = prefix_list_name(plist);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) {
|
||||
if (!strcmp(PREFIX_NAME_IN(oa), name))
|
||||
PREFIX_LIST_IN(oa) = add ? plist : NULL;
|
||||
if (!strcmp(PREFIX_NAME_OUT(oa), name))
|
||||
PREFIX_LIST_OUT(oa) = add ? plist : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DEFUN (area_import_list,
|
||||
area_import_list_cmd,
|
||||
"area A.B.C.D import-list NAME",
|
||||
|
@ -122,6 +122,7 @@ extern void ospf6_area_disable(struct ospf6_area *);
|
||||
|
||||
extern void ospf6_area_show(struct vty *, struct ospf6_area *);
|
||||
|
||||
extern void ospf6_area_plist_update(struct prefix_list *plist, int add);
|
||||
extern void ospf6_area_config_write(struct vty *vty);
|
||||
extern void ospf6_area_init(void);
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "linklist.h"
|
||||
#include "vty.h"
|
||||
#include "command.h"
|
||||
#include "plist.h"
|
||||
|
||||
#include "ospf6_proto.h"
|
||||
#include "ospf6_network.h"
|
||||
@ -1139,6 +1140,20 @@ DEFUN (show_ipv6_ospf6_linkstate_detail,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void ospf6_plist_add(struct prefix_list *plist)
|
||||
{
|
||||
if (prefix_list_afi(plist) != AFI_IP6)
|
||||
return;
|
||||
ospf6_area_plist_update(plist, 1);
|
||||
}
|
||||
|
||||
static void ospf6_plist_del(struct prefix_list *plist)
|
||||
{
|
||||
if (prefix_list_afi(plist) != AFI_IP6)
|
||||
return;
|
||||
ospf6_area_plist_update(plist, 0);
|
||||
}
|
||||
|
||||
/* Install ospf related commands. */
|
||||
void ospf6_init(void)
|
||||
{
|
||||
@ -1154,6 +1169,9 @@ void ospf6_init(void)
|
||||
ospf6_asbr_init();
|
||||
ospf6_abr_init();
|
||||
|
||||
prefix_list_add_hook(ospf6_plist_add);
|
||||
prefix_list_delete_hook(ospf6_plist_del);
|
||||
|
||||
ospf6_bfd_init();
|
||||
install_node(&debug_node, config_write_ospf6_debug);
|
||||
|
||||
|
@ -257,4 +257,4 @@ if __name__ == '__main__':
|
||||
process_file(args.cfile, ofd, dumpfd, args.all_defun)
|
||||
|
||||
if args.o is not None:
|
||||
clippy.wrdiff(args.o, ofd)
|
||||
clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__)])
|
||||
|
@ -16,6 +16,7 @@
|
||||
# with this program; see the file COPYING; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os, stat
|
||||
import _clippy
|
||||
from _clippy import parse, Graph, GraphNode
|
||||
|
||||
@ -47,7 +48,7 @@ def dump(graph):
|
||||
for i, depth in graph_iterate(graph):
|
||||
print('\t%s%s %r' % (' ' * (depth * 2), i.type, i.text))
|
||||
|
||||
def wrdiff(filename, buf):
|
||||
def wrdiff(filename, buf, reffiles = []):
|
||||
'''write buffer to file if contents changed'''
|
||||
|
||||
expl = ''
|
||||
@ -57,8 +58,16 @@ def wrdiff(filename, buf):
|
||||
try: old = open(filename, 'r').read()
|
||||
except: pass
|
||||
if old == buf:
|
||||
for reffile in reffiles:
|
||||
# ensure output timestamp is newer than inputs, for make
|
||||
reftime = os.stat(reffile)[stat.ST_MTIME]
|
||||
outtime = os.stat(filename)[stat.ST_MTIME]
|
||||
if outtime <= reftime:
|
||||
os.utime(filename, (reftime + 1, reftime + 1))
|
||||
# sys.stderr.write('%s unchanged, not written\n' % (filename))
|
||||
return
|
||||
with open('.new.' + filename, 'w') as out:
|
||||
|
||||
newname = '%s.new-%d' % (filename, os.getpid())
|
||||
with open(newname, 'w') as out:
|
||||
out.write(buf)
|
||||
os.rename('.new.' + filename, filename)
|
||||
os.rename(newname, filename)
|
||||
|
@ -23,7 +23,7 @@ static bool atexit_registered;
|
||||
|
||||
static void show_meminfo_at_exit(void)
|
||||
{
|
||||
log_memstats_stderr("isis fuzztest");
|
||||
log_memstats(stderr, "isis fuzztest");
|
||||
}
|
||||
|
||||
static int comp_line(const void *p1, const void *p2)
|
||||
|
@ -53,7 +53,7 @@ static void vty_do_exit(int isexit)
|
||||
thread_master_free(master);
|
||||
closezlog();
|
||||
|
||||
log_memstats_stderr("testcli");
|
||||
log_memstats(stderr, "testcli");
|
||||
if (!isexit)
|
||||
exit(0);
|
||||
}
|
||||
|
@ -1589,8 +1589,10 @@ static int fpm_remote_srv_write(struct vty *vty)
|
||||
|
||||
in.s_addr = zfpm_g->fpm_server;
|
||||
|
||||
if (zfpm_g->fpm_server != FPM_DEFAULT_IP
|
||||
|| zfpm_g->fpm_port != FPM_DEFAULT_PORT)
|
||||
if ((zfpm_g->fpm_server != FPM_DEFAULT_IP
|
||||
&& zfpm_g->fpm_server != INADDR_ANY)
|
||||
|| (zfpm_g->fpm_port != FPM_DEFAULT_PORT
|
||||
&& zfpm_g->fpm_port != 0))
|
||||
vty_out(vty, "fpm connection ip %s port %d\n", inet_ntoa(in),
|
||||
zfpm_g->fpm_port);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user