Merge pull request #1031 from opensourcerouting/small-bits

small bits
This commit is contained in:
Donald Sharp 2017-08-24 08:58:46 -04:00 committed by GitHub
commit 27c5d4de93
29 changed files with 324 additions and 189 deletions

View File

@ -5,7 +5,7 @@ include common.am
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib
AM_CFLAGS = $(WERROR) AM_CFLAGS = $(WERROR)
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE)
LIBCAP = @LIBCAP@ LIBCAP = @LIBCAP@
EXTRA_DIST = EXTRA_DIST =
@ -25,6 +25,14 @@ pkginclude_HEADERS =
nodist_pkginclude_HEADERS = nodist_pkginclude_HEADERS =
dist_examples_DATA = 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 lib/subdir.am
include zebra/subdir.am include zebra/subdir.am
include qpb/subdir.am include qpb/subdir.am

View File

@ -219,9 +219,6 @@ static __attribute__((__noreturn__)) void bgp_exit(int status)
memset(bm, 0, sizeof(*bm)); memset(bm, 0, sizeof(*bm));
frr_fini(); frr_fini();
if (bgp_debug_count())
log_memstats_stderr("bgpd");
exit(status); exit(status);
} }

View File

@ -20,6 +20,7 @@
*/ */
#include <zebra.h> #include <zebra.h>
#include <math.h>
#include "prefix.h" #include "prefix.h"
#include "linklist.h" #include "linklist.h"
@ -9349,6 +9350,7 @@ static const char *table_stats_strs[] = {
struct bgp_table_stats { struct bgp_table_stats {
struct bgp_table *table; struct bgp_table *table;
unsigned long long counts[BGP_STATS_MAX]; unsigned long long counts[BGP_STATS_MAX];
double total_space;
}; };
#if 0 #if 0
@ -9417,8 +9419,8 @@ static int bgp_table_stats_walker(struct thread *t)
ts->counts[BGP_STATS_UNAGGREGATEABLE]++; ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
/* announced address space */ /* announced address space */
if (space) if (space)
ts->counts[BGP_STATS_SPACE] += ts->total_space += pow(2.0,
1 << (space - rn->p.prefixlen); space - rn->p.prefixlen);
} else if (prn->info) } else if (prn->info)
ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++; 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; break;
case BGP_STATS_SPACE: case BGP_STATS_SPACE:
vty_out(vty, "%-30s: ", table_stats_strs[i]); vty_out(vty, "%-30s: ", table_stats_strs[i]);
vty_out(vty, "%12llu\n", ts.counts[i]); vty_out(vty, "%12g\n", ts.total_space);
if (ts.counts[BGP_STATS_MAXBITLEN] < 9)
break; if (afi == AFI_IP6) {
vty_out(vty, "%30s: ", "%% announced "); 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", vty_out(vty, "%12.2f\n",
100 * (float)ts.counts[BGP_STATS_SPACE] ts.total_space * 100. * pow(2.0, -32));
/ (float)((uint64_t)1UL
<< ts.counts
[BGP_STATS_MAXBITLEN]));
vty_out(vty, "%30s: ", "/8 equivalent "); vty_out(vty, "%30s: ", "/8 equivalent ");
vty_out(vty, "%12.2f\n", vty_out(vty, "%12.2f\n",
(float)ts.counts[BGP_STATS_SPACE] ts.total_space * pow(2.0, -32+8));
/ (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, "%30s: ", "/24 equivalent ");
vty_out(vty, "%12.2f", vty_out(vty, "%12.2f\n",
(float)ts.counts[BGP_STATS_SPACE] ts.total_space * pow(2.0, -32+24));
/ (float)(1UL }
<< (ts.counts
[BGP_STATS_MAXBITLEN]
- 24)));
break; break;
default: default:
vty_out(vty, "%-30s: ", table_stats_strs[i]); vty_out(vty, "%-30s: ", table_stats_strs[i]);

View File

@ -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 SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h
.c_clippy.c: .c_clippy.c:
@{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; } @{ 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 $(AM_V_CLIPPY)$(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py -o $@ $<
@{ test -f $@ && diff $@.tmp $@ >/dev/null 2>/dev/null; } && rm $@.tmp || mv $@.tmp $@
## automake's "ylwrap" is a great piece of GNU software... not. ## automake's "ylwrap" is a great piece of GNU software... not.
.l.c: .l.c:

View File

@ -11,14 +11,28 @@ def run(cmd):
proc.wait() proc.wait()
return rv return rv
clangfmt = run(['git', 'show', 'master:.clang-format'])
argp = argparse.ArgumentParser(description = 'git whitespace-fixing tool') argp = argparse.ArgumentParser(description = 'git whitespace-fixing tool')
argp.add_argument('branch', metavar='BRANCH', type = str, nargs = '?', default = 'HEAD') argp.add_argument('branch', metavar='BRANCH', type = str, nargs = '?', default = 'HEAD')
args = argp.parse_args() args = argp.parse_args()
branch = args.branch branch = args.branch
commit = run(['git', 'rev-list', '-n', '1', branch, '--']).strip() 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() beforebase = run(['git', 'merge-base', commit, beforeid]).strip()
afterbase = run(['git', 'merge-base', commit, afterid]).strip() afterbase = run(['git', 'merge-base', commit, afterid]).strip()
@ -28,10 +42,10 @@ if afterbase == afterid:
sys.exit(1) sys.exit(1)
if beforebase != beforeid: 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) 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() revs.reverse()
srcdir = os.getcwd() srcdir = os.getcwd()
@ -39,9 +53,12 @@ tmpdir = tempfile.mkdtemp('frrindent')
os.chdir(tmpdir) os.chdir(tmpdir)
sys.stderr.write('using temporary directory %s; %d revisions\n' % (tmpdir, len(revs))) 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') os.chdir('repo')
with open('.clang-format', 'w') as fd:
fd.write(clangfmt)
prev = beforeid prev = beforeid
for rev in revs: for rev in revs:
filestat = run(['git', 'diff', '-z', '--name-status', prev, rev]).rstrip('\0').split('\0') filestat = run(['git', 'diff', '-z', '--name-status', prev, rev]).rstrip('\0').split('\0')

View File

@ -42,6 +42,7 @@
#include "command_graph.h" #include "command_graph.h"
#include "qobj.h" #include "qobj.h"
#include "defaults.h" #include "defaults.h"
#include "libfrr.h"
DEFINE_MTYPE(LIB, HOST, "Host config") DEFINE_MTYPE(LIB, HOST, "Host config")
DEFINE_MTYPE(LIB, STRVEC, "String vector") DEFINE_MTYPE(LIB, STRVEC, "String vector")
@ -359,21 +360,23 @@ void install_element(enum node_type ntype, struct cmd_element *cmd)
return; return;
} }
cnode = vector_slot(cmdvec, ntype); cnode = vector_lookup(cmdvec, ntype);
if (cnode == NULL) { if (cnode == NULL) {
fprintf(stderr, fprintf(stderr,
"Command node %d doesn't exist, please check it\n", "%s[%s]:\n"
ntype); "\tnode %d (%s) does not exist.\n"
fprintf(stderr, "\tplease call install_node() before install_element()\n",
"Have you called install_node before this install_element?\n"); cmd->name, cmd->string, ntype, node_names[ntype]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (hash_lookup(cnode->cmd_hash, cmd) != NULL) { if (hash_lookup(cnode->cmd_hash, cmd) != NULL) {
fprintf(stderr, fprintf(stderr,
"Multiple command installs to node %d of command:\n%s\n", "%s[%s]:\n"
ntype, cmd->string); "\tnode %d (%s) already has this command installed.\n"
"\tduplicate install_element call?\n",
cmd->name, cmd->string, ntype, node_names[ntype]);
return; return;
} }
@ -406,21 +409,23 @@ void uninstall_element(enum node_type ntype, struct cmd_element *cmd)
return; return;
} }
cnode = vector_slot(cmdvec, ntype); cnode = vector_lookup(cmdvec, ntype);
if (cnode == NULL) { if (cnode == NULL) {
fprintf(stderr, fprintf(stderr,
"Command node %d doesn't exist, please check it\n", "%s[%s]:\n"
ntype); "\tnode %d (%s) does not exist.\n"
fprintf(stderr, "\tplease call install_node() before uninstall_element()\n",
"Have you called install_node before this install_element?\n"); cmd->name, cmd->string, ntype, node_names[ntype]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (hash_release(cnode->cmd_hash, cmd) == NULL) { if (hash_release(cnode->cmd_hash, cmd) == NULL) {
fprintf(stderr, fprintf(stderr,
"Trying to uninstall non-installed command (node %d):\n%s\n", "%s[%s]:\n"
ntype, cmd->string); "\tnode %d (%s) does not have this command installed.\n"
"\tduplicate uninstall_element call?\n",
cmd->name, cmd->string, ntype, node_names[ntype]);
return; return;
} }
@ -555,6 +560,9 @@ static int config_write_host(struct vty *vty)
else if (!host.motd) else if (!host.motd)
vty_out(vty, "no banner motd\n"); vty_out(vty, "no banner motd\n");
if (debug_memstats_at_exit)
vty_out(vty, "!\ndebug memstats-at-exit\n");
return 1; return 1;
} }
@ -2366,6 +2374,17 @@ DEFUN (no_config_log_timestamp_precision,
return CMD_SUCCESS; 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 cmd_banner_motd_file(const char *file)
{ {
int success = CMD_SUCCESS; int success = CMD_SUCCESS;
@ -2527,6 +2546,7 @@ void cmd_init(int terminal)
/* Each node's basic commands. */ /* Each node's basic commands. */
install_element(VIEW_NODE, &show_version_cmd); install_element(VIEW_NODE, &show_version_cmd);
install_element(ENABLE_NODE, &show_startup_config_cmd); install_element(ENABLE_NODE, &show_startup_config_cmd);
install_element(ENABLE_NODE, &debug_memstats_cmd);
if (terminal) { if (terminal) {
install_element(VIEW_NODE, &config_list_cmd); 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, &hostname_cmd);
install_element(CONFIG_NODE, &no_hostname_cmd); install_element(CONFIG_NODE, &no_hostname_cmd);
install_element(CONFIG_NODE, &frr_version_defaults_cmd); install_element(CONFIG_NODE, &frr_version_defaults_cmd);
install_element(CONFIG_NODE, &debug_memstats_cmd);
if (terminal > 0) { if (terminal > 0) {
install_element(CONFIG_NODE, &password_cmd); install_element(CONFIG_NODE, &password_cmd);

81
lib/compiler.h Normal file
View 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 */

View File

@ -404,7 +404,8 @@ DEFUN (grammar_findambig,
nodegraph = cnode->cmdgraph; nodegraph = cnode->cmdgraph;
if (!nodegraph) if (!nodegraph)
continue; 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); commands = cmd_graph_permutations(nodegraph);

View File

@ -52,6 +52,8 @@ char frr_zclientpath[256];
static char pidfile_default[256]; static char pidfile_default[256];
static char vtypath_default[256]; static char vtypath_default[256];
bool debug_memstats_at_exit = 0;
static char comb_optstr[256]; static char comb_optstr[256];
static struct option comb_lo[64]; static struct option comb_lo[64];
static struct option *comb_next_lo = &comb_lo[0]; static struct option *comb_next_lo = &comb_lo[0];
@ -639,7 +641,10 @@ static void frr_daemon_wait(int fd)
exit(0); exit(0);
/* child failed one way or another ... */ /* 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, fprintf(stderr, "%s failed to start, exited %d\n", di->name,
WEXITSTATUS(exitstat)); WEXITSTATUS(exitstat));
else if (WIFSIGNALED(exitstat)) else if (WIFSIGNALED(exitstat))
@ -841,6 +846,10 @@ void frr_early_fini(void)
void frr_fini(void) void frr_fini(void)
{ {
FILE *fp;
char filename[128];
int have_leftovers;
hook_call(frr_fini); hook_call(frr_fini);
/* memory_init -> nothing needed */ /* memory_init -> nothing needed */
@ -851,4 +860,28 @@ void frr_fini(void)
thread_master_free(master); thread_master_free(master);
closezlog(); closezlog();
/* frrmod_init -> nothing needed / hooks */ /* 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);
}
} }

View File

@ -121,4 +121,6 @@ extern const char frr_moduledir[];
extern char frr_protoname[]; extern char frr_protoname[];
extern char frr_protonameinst[]; extern char frr_protonameinst[];
extern bool debug_memstats_at_exit;
#endif /* _ZEBRA_FRR_H */ #endif /* _ZEBRA_FRR_H */

View File

@ -701,7 +701,7 @@ void _zlog_assert_failed(const char *assertion, const char *file,
assertion, file, line, (function ? function : "?")); assertion, file, line, (function ? function : "?"));
zlog_backtrace(LOG_CRIT); zlog_backtrace(LOG_CRIT);
zlog_thread_info(LOG_CRIT); zlog_thread_info(LOG_CRIT);
log_memstats_stderr("log"); log_memstats(stderr, "log");
abort(); abort();
} }

View File

@ -104,6 +104,7 @@ int qmem_walk(qmem_walk_fn *func, void *arg)
} }
struct exit_dump_args { struct exit_dump_args {
FILE *fp;
const char *prefix; const char *prefix;
int error; 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; struct exit_dump_args *eda = arg;
if (!mt) { if (!mt) {
fprintf(stderr, fprintf(eda->fp,
"%s: showing active allocations in " "%s: showing active allocations in "
"memory group %s\n", "memory group %s\n",
eda->prefix, mg->name); eda->prefix, mg->name);
@ -122,15 +123,16 @@ static int qmem_exit_walker(void *arg, struct memgroup *mg, struct memtype *mt)
char size[32]; char size[32];
eda->error++; eda->error++;
snprintf(size, sizeof(size), "%10zu", mt->size); 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, eda->prefix, mt->name, mt->n_alloc,
mt->size == SIZE_VAR ? "(variably sized)" : size); mt->size == SIZE_VAR ? "(variably sized)" : size);
} }
return 0; 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); qmem_walk(qmem_exit_walker, &eda);
return eda.error;
} }

View File

@ -18,7 +18,9 @@
#define _QUAGGA_MEMORY_H #define _QUAGGA_MEMORY_H
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <frratomic.h> #include <frratomic.h>
#include "compiler.h"
#define array_size(ar) (sizeof(ar) / sizeof(ar[0])) #define array_size(ar) (sizeof(ar) / sizeof(ar[0]))
@ -36,41 +38,6 @@ struct memgroup {
const char *name; 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: /* macro usage:
* *
* mydaemon.h * mydaemon.h
@ -194,7 +161,8 @@ static inline size_t mtype_stats_alloc(struct memtype *mt)
* last value from qmem_walk_fn. */ * last value from qmem_walk_fn. */
typedef int qmem_walk_fn(void *arg, struct memgroup *mg, struct memtype *mt); typedef int qmem_walk_fn(void *arg, struct memgroup *mg, struct memtype *mt);
extern int qmem_walk(qmem_walk_fn *func, void *arg); 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); extern void memory_oom(size_t size, const char *name);

View File

@ -122,6 +122,14 @@ const char *prefix_list_name(struct prefix_list *plist)
return plist->name; 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. */ /* Lookup prefix_list from list of prefix_list by name. */
static struct prefix_list *prefix_list_lookup_do(afi_t afi, int orf, static struct prefix_list *prefix_list_lookup_do(afi_t afi, int orf,
const char *name) const char *name)

View File

@ -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 void prefix_list_delete_hook(void (*func)(struct prefix_list *));
extern const char *prefix_list_name(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 struct prefix_list *prefix_list_lookup(afi_t, const char *);
extern enum prefix_list_type prefix_list_apply(struct prefix_list *, void *); extern enum prefix_list_type prefix_list_apply(struct prefix_list *, void *);

View File

@ -1263,5 +1263,6 @@ unsigned prefix_hash_key(void *pp)
* padding and unused prefix bytes. */ * padding and unused prefix bytes. */
memset(&copy, 0, sizeof(copy)); memset(&copy, 0, sizeof(copy));
prefix_copy(&copy, (struct prefix *)pp); prefix_copy(&copy, (struct prefix *)pp);
return jhash(&copy, sizeof(copy), 0x55aa5a5a); return jhash(&copy, offsetof(struct prefix, u.prefix)
+ PSIZE(copy.prefixlen), 0x55aa5a5a);
} }

View File

@ -33,28 +33,13 @@
#endif #endif
#include "sockunion.h" #include "sockunion.h"
#include "ipaddr.h" #include "ipaddr.h"
#include "compiler.h"
#ifndef ETH_ALEN #ifndef ETH_ALEN
#define ETH_ALEN 6 #define ETH_ALEN 6
#endif #endif
/* for compatibility */ /* 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 #ifdef ETHER_ADDR_LEN
#undef ETHER_ADDR_LEN #undef ETHER_ADDR_LEN
#endif #endif

View File

@ -245,7 +245,7 @@ core_handler(int signo
#endif #endif
); );
/* dump memory stats on core */ /* dump memory stats on core */
log_memstats_stderr("core_handler"); log_memstats(stderr, "core_handler");
abort(); abort();
} }

View File

@ -85,6 +85,7 @@ pkginclude_HEADERS += \
lib/command.h \ lib/command.h \
lib/command_graph.h \ lib/command_graph.h \
lib/command_match.h \ lib/command_match.h \
lib/compiler.h \
lib/csv.h \ lib/csv.h \
lib/distribute.h \ lib/distribute.h \
lib/event_counter.h \ lib/event_counter.h \

View File

@ -25,6 +25,7 @@
#include "log.h" #include "log.h"
#include "sockunion.h" #include "sockunion.h"
#include "qobj.h" #include "qobj.h"
#include "compiler.h"
#define VTY_BUFSIZ 4096 #define VTY_BUFSIZ 4096
#define VTY_MAXHIST 20 #define VTY_MAXHIST 20
@ -182,23 +183,11 @@ struct vty_arg {
/* Integrated configuration file. */ /* Integrated configuration file. */
#define INTEGRATE_DEFAULT_CONFIG "frr.conf" #define INTEGRATE_DEFAULT_CONFIG "frr.conf"
/* for compatibility */ #if CONFDATE > 20180401
#if defined(__ICC) CPP_NOTICE("It's probably time to remove VTY_NEWLINE compatibility foo.")
#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 #endif
/* for compatibility */
#define VNL "\n" CPP_WARN("VNL has been replaced with \\n.") #define VNL "\n" CPP_WARN("VNL has been replaced with \\n.")
#define VTYNL "\n" CPP_WARN("VTYNL 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.") #define VTY_NEWLINE "\n" CPP_WARN("VTY_NEWLINE has been replaced with \\n.")

View File

@ -386,14 +386,8 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
} }
/* Check filter-list */ /* 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_OUT(area))
if (prefix_list_apply(PREFIX_LIST_OUT(area), if (prefix_list_apply(PREFIX_LIST_OUT(area), &route->prefix)
&route->prefix)
!= PREFIX_PERMIT) { != PREFIX_PERMIT) {
if (is_debug) { if (is_debug) {
inet_ntop(AF_INET, inet_ntop(AF_INET,
@ -406,7 +400,6 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
} }
return 0; return 0;
} }
}
/* the route is going to be originated. store it in area's summary_table /* the route is going to be originated. store it in area's summary_table
*/ */
@ -873,11 +866,6 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
} }
/* Check input prefix-list */ /* 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_IN(oa))
if (prefix_list_apply(PREFIX_LIST_IN(oa), &prefix) if (prefix_list_apply(PREFIX_LIST_IN(oa), &prefix)
!= PREFIX_PERMIT) { != PREFIX_PERMIT) {
@ -888,7 +876,6 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
ospf6_route_remove(old, table); ospf6_route_remove(old, table);
return; return;
} }
}
/* (5),(6): the path preference is handled by the sorting /* (5),(6): the path preference is handled by the sorting
in the routing table. Always install the path by substituting in the routing table. Always install the path by substituting

View File

@ -45,6 +45,8 @@
#include "ospf6_asbr.h" #include "ospf6_asbr.h"
#include "ospf6d.h" #include "ospf6d.h"
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name")
int ospf6_area_cmp(void *va, void *vb) int ospf6_area_cmp(void *va, void *vb)
{ {
struct ospf6_area *oa = (struct ospf6_area *)va; struct ospf6_area *oa = (struct ospf6_area *)va;
@ -579,17 +581,15 @@ DEFUN (area_filter_list,
plist = prefix_list_lookup(AFI_IP6, plistname); plist = prefix_list_lookup(AFI_IP6, plistname);
if (strmatch(inout, "in")) { if (strmatch(inout, "in")) {
PREFIX_LIST_IN(area) = plist; PREFIX_LIST_IN(area) = plist;
if (PREFIX_NAME_IN(area)) XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area));
free(PREFIX_NAME_IN(area)); PREFIX_NAME_IN(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME,
plistname);
PREFIX_NAME_IN(area) = strdup(plistname);
ospf6_abr_reimport(area); ospf6_abr_reimport(area);
} else { } else {
PREFIX_LIST_OUT(area) = plist; PREFIX_LIST_OUT(area) = plist;
if (PREFIX_NAME_OUT(area)) XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area));
free(PREFIX_NAME_OUT(area)); PREFIX_NAME_OUT(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME,
plistname);
PREFIX_NAME_OUT(area) = strdup(plistname);
ospf6_abr_enable_area(area); ospf6_abr_enable_area(area);
} }
@ -622,27 +622,34 @@ DEFUN (no_area_filter_list,
return CMD_SUCCESS; return CMD_SUCCESS;
PREFIX_LIST_IN(area) = NULL; PREFIX_LIST_IN(area) = NULL;
if (PREFIX_NAME_IN(area)) XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area));
free(PREFIX_NAME_IN(area));
PREFIX_NAME_IN(area) = NULL;
ospf6_abr_reimport(area); ospf6_abr_reimport(area);
} else { } else {
if (PREFIX_NAME_OUT(area)) if (PREFIX_NAME_OUT(area))
if (!strmatch(PREFIX_NAME_OUT(area), plistname)) if (!strmatch(PREFIX_NAME_OUT(area), plistname))
return CMD_SUCCESS; return CMD_SUCCESS;
PREFIX_LIST_OUT(area) = NULL; XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area));
if (PREFIX_NAME_OUT(area))
free(PREFIX_NAME_OUT(area));
PREFIX_NAME_OUT(area) = NULL;
ospf6_abr_enable_area(area); ospf6_abr_enable_area(area);
} }
return CMD_SUCCESS; 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, DEFUN (area_import_list,
area_import_list_cmd, area_import_list_cmd,
"area A.B.C.D import-list NAME", "area A.B.C.D import-list NAME",

View File

@ -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_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_config_write(struct vty *vty);
extern void ospf6_area_init(void); extern void ospf6_area_init(void);

View File

@ -24,6 +24,7 @@
#include "linklist.h" #include "linklist.h"
#include "vty.h" #include "vty.h"
#include "command.h" #include "command.h"
#include "plist.h"
#include "ospf6_proto.h" #include "ospf6_proto.h"
#include "ospf6_network.h" #include "ospf6_network.h"
@ -1139,6 +1140,20 @@ DEFUN (show_ipv6_ospf6_linkstate_detail,
return CMD_SUCCESS; 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. */ /* Install ospf related commands. */
void ospf6_init(void) void ospf6_init(void)
{ {
@ -1154,6 +1169,9 @@ void ospf6_init(void)
ospf6_asbr_init(); ospf6_asbr_init();
ospf6_abr_init(); ospf6_abr_init();
prefix_list_add_hook(ospf6_plist_add);
prefix_list_delete_hook(ospf6_plist_del);
ospf6_bfd_init(); ospf6_bfd_init();
install_node(&debug_node, config_write_ospf6_debug); install_node(&debug_node, config_write_ospf6_debug);

View File

@ -257,4 +257,4 @@ if __name__ == '__main__':
process_file(args.cfile, ofd, dumpfd, args.all_defun) process_file(args.cfile, ofd, dumpfd, args.all_defun)
if args.o is not None: if args.o is not None:
clippy.wrdiff(args.o, ofd) clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__)])

View File

@ -16,6 +16,7 @@
# with this program; see the file COPYING; if not, write to the Free Software # 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 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import os, stat
import _clippy import _clippy
from _clippy import parse, Graph, GraphNode from _clippy import parse, Graph, GraphNode
@ -47,7 +48,7 @@ def dump(graph):
for i, depth in graph_iterate(graph): for i, depth in graph_iterate(graph):
print('\t%s%s %r' % (' ' * (depth * 2), i.type, i.text)) 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''' '''write buffer to file if contents changed'''
expl = '' expl = ''
@ -57,8 +58,16 @@ def wrdiff(filename, buf):
try: old = open(filename, 'r').read() try: old = open(filename, 'r').read()
except: pass except: pass
if old == buf: 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)) # sys.stderr.write('%s unchanged, not written\n' % (filename))
return return
with open('.new.' + filename, 'w') as out:
newname = '%s.new-%d' % (filename, os.getpid())
with open(newname, 'w') as out:
out.write(buf) out.write(buf)
os.rename('.new.' + filename, filename) os.rename(newname, filename)

View File

@ -23,7 +23,7 @@ static bool atexit_registered;
static void show_meminfo_at_exit(void) 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) static int comp_line(const void *p1, const void *p2)

View File

@ -53,7 +53,7 @@ static void vty_do_exit(int isexit)
thread_master_free(master); thread_master_free(master);
closezlog(); closezlog();
log_memstats_stderr("testcli"); log_memstats(stderr, "testcli");
if (!isexit) if (!isexit)
exit(0); exit(0);
} }

View File

@ -1589,8 +1589,10 @@ static int fpm_remote_srv_write(struct vty *vty)
in.s_addr = zfpm_g->fpm_server; in.s_addr = zfpm_g->fpm_server;
if (zfpm_g->fpm_server != FPM_DEFAULT_IP if ((zfpm_g->fpm_server != FPM_DEFAULT_IP
|| zfpm_g->fpm_port != FPM_DEFAULT_PORT) && 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), vty_out(vty, "fpm connection ip %s port %d\n", inet_ntoa(in),
zfpm_g->fpm_port); zfpm_g->fpm_port);