From: Katerina Kubecova Date: Thu, 6 Mar 2025 10:24:05 +0000 (+0100) Subject: why the imports do not work? X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f8a4a9a57cf7be0c3de293022158b9d1cc654fe5;p=thirdparty%2Fbird.git why the imports do not work? --- diff --git a/Makefile.in b/Makefile.in index 839efe243..aed6dbc22 100644 --- a/Makefile.in +++ b/Makefile.in @@ -12,7 +12,8 @@ LDFLAGS=@LDFLAGS@ M4FLAGS=@M4FLAGS@ BISONFLAGS=@BISONFLAGS@ LIBS=@LIBS@ -DAEMON_LIBS=@DAEMON_LIBS@ +COMMON_LIBS=@COMMON_LIBS@ +DAEMON_LIBS=@DAEMON_LIBS@ $(COMMON_LIBS) CLIENT_LIBS=@CLIENT_LIBS@ CC=@CC@ M4=@M4@ @@ -25,6 +26,7 @@ INSTALL_DATA=@INSTALL_DATA@ client=$(addprefix $(exedir)/,@CLIENT@) daemon=$(exedir)/bird +common-lib=$(objdir)/libbird.o.txt protocols=@protocols@ PROTO_BUILD := $(protocols) dev kif krt @@ -88,6 +90,7 @@ tests-target-files = $(patsubst %.c,$(o)%,$(tests_src)) all-daemon = $(daemon): $(obj) all-client = $(client): $(obj) +all-lib = $(common-lib): $(obj) s = $(dir $(lastword $(MAKEFILE_LIST))) ifeq ($(srcdir),.) @@ -156,9 +159,24 @@ $(objdir)/.dir-stamp: Makefile $(Q)mkdir -p $(addprefix $(objdir)/,$(dirs) doc) $(Q)touch $@ +# Composing static library; older GCC's and linkers somehow fail +# both with partial linking with LTO and also with static library creation, +# thus we just collect all the deps and add them to the final build +$(common-lib): + $(E)echo TXT $^ > $@ + $(Q)echo $^ > $@ +# Some time in future, somebody may want to try the following recipe again +# $(E)echo LD $(LDFLAGS) -r -o $@ $^ +# +$(Q)$(CC) $(LDFLAGS) -r -o $@ $^ + +# The lib must be linked last +$(daemon): $(common-lib) + +#$(warning $(patsubst $(common-lib),$(shell cat $(common-lib)),whatever obj/libbird.o.txt)) + $(client) $(daemon): $(E)echo LD $(LDFLAGS) -o $@ $^ $(LIBS) - $(Q)$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) + +$(Q)$(CC) $(LDFLAGS) -o $@ $(patsubst $(common-lib),$(shell cat $(common-lib)),$^) $(LIBS) $(objdir)/sysdep/paths.h: Makefile $(E)echo GEN $@ @@ -171,9 +189,9 @@ $(objdir)/sysdep/paths.h: Makefile tests_targets_ok = $(addsuffix .ok,$(tests_targets)) -$(tests_targets): %: %.o $(tests_objs) | prepare +$(tests_targets): %: %.o $(tests_objs) $(common-lib) | prepare $(E)echo LD $(LDFLAGS) -o $@ $< "..." $(LIBS) - $(Q)$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) + +$(Q)$(CC) $(LDFLAGS) -o $@ $(patsubst $(common-lib),$(shell cat $(common-lib)),$^) $(LIBS) # Hack to avoid problems with tests linking everything $(tests_targets): LIBS += $(DAEMON_LIBS) @@ -222,6 +240,7 @@ install-docs: clean:: rm -f $(objdir)/sysdep/paths.h $(objdir)/nest/proto-build.c rm -f $(addprefix $(exedir)/,bird birdc birdcl) + rm -f $(common-lib) find $(objdir) -name "*.[od]" -exec rm -f '{}' '+' testsclean: diff --git a/aclocal.m4 b/aclocal.m4 index 893925058..dd5cca359 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -2,6 +2,25 @@ dnl ** Additional Autoconf tests for BIRD configure script dnl ** (c) 1999 Martin Mares dnl ** (c) 2021 Maria Matejka +# simplified adapted macro AX_COMPILER_VENDOR from autotools +AC_DEFUN([BIRD_COMPILER_VENDOR], +[ + AC_CACHE_CHECK( + [which compiler vendor we are dealing with], + [bird_cv_compiler_vendor], + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ int x = __clang__; ], []) + ], + [bird_cv_compiler_vendor=llvm], + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ int x = __GNUC__; ], []) + ], + [bird_cv_compiler_vendor=gnu], + [bird_cv_compiler_vendor=unknown] + )) + ) +]) + AC_DEFUN([BIRD_CHECK_POINTER_ALIGNMENT], [ AC_CACHE_CHECK( @@ -239,8 +258,8 @@ AC_DEFUN([BIRD_CHECK_LTO], [ bird_tmp_cflags="$CFLAGS" bird_tmp_ldflags="$LDFLAGS" - CFLAGS="-flto" - LDFLAGS="-flto=4" + CFLAGS="$1" + LDFLAGS="$2" AC_CACHE_CHECK( [whether link time optimizer is available], diff --git a/conf/conf.c b/conf/conf.c index 73e0ae050..580d96b40 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -75,7 +75,6 @@ static void config_done(void); static timer *config_timer; /* Timer for scheduled configuration rollback */ /* These are public just for cmd_show_status(), should not be accessed elsewhere */ -int shutting_down; /* Shutdown requested, do not accept new config changes */ int configuring; /* Reconfiguration is running */ int undo_available; /* Undo was not requested from last reconfiguration */ /* Note that both shutting_down and undo_available are related to requests, not processing */ @@ -113,9 +112,9 @@ config_alloc(const char *name) c->pool = p; c->mem = l; c->file_name = ndup; - c->tf_route = c->tf_proto = TM_ISO_SHORT_MS; - c->tf_base = c->tf_log = TM_ISO_LONG_MS; - c->gr_wait = DEFAULT_GR_WAIT; + c->runtime.tf_route = c->runtime.tf_proto = TM_ISO_SHORT_MS; + c->runtime.tf_base = c->runtime.tf_log = TM_ISO_LONG_MS; + c->runtime.gr_wait = DEFAULT_GR_WAIT; callback_init(&c->obstacles_cleared, config_obstacles_cleared, &main_birdloop); obstacle_target_init(&c->obstacles, &c->obstacles_cleared, p, "Config"); @@ -232,42 +231,15 @@ config_free_old(void) } } -struct global_runtime global_runtime_internal[2] = {{ - .tf_log = { - .fmt1 = "%F %T.%3f", - }, -}}; -struct global_runtime * _Atomic global_runtime = &global_runtime_internal[0]; - static void global_commit(struct config *new, struct config *old) { /* Updating the global runtime. */ - struct global_runtime *og = atomic_load_explicit(&global_runtime, memory_order_relaxed); - struct global_runtime *ng = &global_runtime_internal[og == &global_runtime_internal[0]]; - ASSERT_DIE(ng != og); - -#define COPY(x) ng->x = new->x; - MACRO_FOREACH(COPY, - tf_route, - tf_proto, - tf_log, - tf_base, - cli_debug, - latency_debug, - latency_limit, - watchdog_warning, - watchdog_timeout, - gr_wait, - hostname - ); -#undef COPY - - ng->load_time = current_time(); - - if (new->router_id) - ng->router_id = new->router_id; - else if (old) + union bird_global_runtime *ng = &new->runtime; + SKIP_BACK_DECLARE(union bird_global_runtime, og, generic, + atomic_load_explicit(&global_runtime, memory_order_relaxed)); + + if (!ng->router_id && old) { /* The startup router ID must be determined after start of device protocol, * thus if old == NULL then we do nothing */ @@ -283,10 +255,7 @@ global_commit(struct config *new, struct config *old) } } - atomic_store_explicit(&global_runtime, ng, memory_order_release); - - /* We have to wait until every reader surely doesn't read the old values */ - synchronize_rcu(); + switch_runtime(&ng->generic); } static int @@ -309,11 +278,11 @@ config_do_commit(config_ref *cr, int type) OBSREF_CLEAR(config); OBSREF_SET(config, OBSREF_GET(*cr)); - if (!c->hostname) + if (!c->runtime.hostname) { - c->hostname = get_hostname(c->mem); + c->runtime.hostname = get_hostname(c->mem); - if (!c->hostname) + if (!c->runtime.hostname) log(L_WARN "Cannot determine hostname"); } diff --git a/conf/conf.h b/conf/conf.h index 0367ebc46..eb7ae6e92 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -13,6 +13,7 @@ #include "lib/ip.h" #include "lib/hash.h" #include "lib/resource.h" +#include "lib/runtime.h" #include "lib/obstacle.h" #include "lib/timer.h" #include "lib/tlists.h" @@ -34,33 +35,30 @@ struct config { struct symbol *def_tables[NET_MAX]; /* Default routing tables for each network */ struct iface_patt *router_id_from; /* Configured list of router ID iface patterns */ - u32 router_id; /* Our Router ID */ u32 proto_default_debug; /* Default protocol debug mask */ u32 proto_default_mrtdump; /* Default protocol mrtdump mask */ u32 channel_default_debug; /* Default channel debug mask */ u32 table_default_debug; /* Default table debug mask */ u32 show_route_debug; /* Exports to CLI debug mask */ u16 filter_vstk, filter_estk; /* Filter stack depth */ - struct timeformat tf_route; /* Time format for 'show route' */ - struct timeformat tf_proto; /* Time format for 'show protocol' */ - struct timeformat tf_log; /* Time format for the logfile */ - struct timeformat tf_base; /* Time format for other purposes */ - u32 gr_wait; /* Graceful restart wait timeout (sec) */ - const char *hostname; /* Hostname */ - - int cli_debug; /* Tracing of CLI connections and commands */ - enum latency_debug_flags { - DL_PING = 1, - DL_WAKEUP = 2, - DL_SCHEDULING = 4, - DL_ALLOCATOR = 8, - DL_SOCKETS = 0x10, - DL_EVENTS = 0x20, - DL_TIMERS = 0x40, - } latency_debug; /* I/O loops log information about task scheduling */ - u32 latency_limit; /* Events with longer duration are logged (us) */ - u32 watchdog_warning; /* I/O loop watchdog limit for warning (us) */ - u32 watchdog_timeout; /* Watchdog timeout (in seconds, 0 = disabled) */ + + union bird_global_runtime { + struct global_runtime generic; + struct { + GLOBAL_RUNTIME_CONTENTS; + + struct timeformat tf_route; /* Time format for 'show route' */ + struct timeformat tf_proto; /* Time format for 'show protocol' */ + + u32 gr_wait; /* Graceful restart wait timeout (sec) */ + + u32 router_id; /* Our Router ID */ + + int cli_debug; /* Tracing of CLI connections and commands */ + u32 watchdog_timeout; /* Watchdog timeout (in seconds, 0 = disabled) */ + }; + } runtime; + char *err_msg; /* Parser error message */ int err_lino; /* Line containing error */ int err_chno; /* Character where the parser stopped */ @@ -70,6 +68,8 @@ struct config { int thread_group_simple; /* Simple variant of thread configuration */ TLIST_LIST(thread_group_config) thread_group; /* Configured thread groups */ struct thread_group_config *default_thread_group; + int thread_count; /* How many worker threads to prefork */ + struct thread_config threads; /* Thread settings */ struct sym_scope *root_scope; /* Scope for root symbols */ struct sym_scope *current_scope; /* Current scope where we are actually in while parsing */ @@ -80,29 +80,11 @@ struct config { int gr_down; /* This is a pseudo-config for graceful restart */ }; -struct global_runtime { - struct timeformat tf_route; /* Time format for 'show route' */ - struct timeformat tf_proto; /* Time format for 'show protocol' */ - struct timeformat tf_log; /* Time format for the logfile */ - struct timeformat tf_base; /* Time format for other purposes */ - - u32 gr_wait; /* Graceful restart wait timeout (sec) */ - - u32 router_id; /* Our Router ID */ - const char *hostname; /* Hostname */ - - btime load_time; /* When we reconfigured last time */ - int cli_debug; /* Tracing of CLI connections and commands */ - enum latency_debug_flags latency_debug; - u32 latency_limit; /* Events with longer duration are logged (us) */ - u32 watchdog_warning; /* I/O loop watchdog limit for warning (us) */ - u32 watchdog_timeout; /* Watchdog timeout (in seconds, 0 = disabled) */ - - struct thread_group *default_thread_group; /* Default thread group if not specified otherwise */ -}; - extern struct global_runtime * _Atomic global_runtime; +/* BIRD's global runtime accessor */ +#define BIRD_GLOBAL_RUNTIME SKIP_BACK(union bird_global_runtime, generic, atomic_load_explicit(&global_runtime, memory_order_relaxed)) + /* Please don't use these variables in protocols. Use proto_config->global instead. */ typedef OBSREF(struct config) config_ref; diff --git a/conf/flowspec.Y b/conf/flowspec.Y index 102fed455..7bb307462 100644 --- a/conf/flowspec.Y +++ b/conf/flowspec.Y @@ -18,6 +18,93 @@ CF_DEFINES struct flow_builder *this_flow; +/** + * flow_check_cf_value_length - check value by flowspec component type + * @fb: flow builder instance + * @val: value + * + * This function checks if the value is in range of component's type support. + * If some problem will appear, the function calls cf_error() function with + * a textual description of reason to failing of validation. + */ +static void +flow_check_cf_value_length(struct flow_builder *fb, u32 val) +{ + enum flow_type t = fb->this_type; + u8 max = flow_max_value_length(t, fb->ipv6); + + if (t == FLOW_TYPE_DSCP && val > 0x3f) + cf_error("%s value %u out of range (0-63)", flow_type_str(t, fb->ipv6), val); + + if (max == 1 && (val > 0xff)) + cf_error("%s value %u out of range (0-255)", flow_type_str(t, fb->ipv6), val); + + if (max == 2 && (val > 0xffff)) + cf_error("%s value %u out of range (0-65535)", flow_type_str(t, fb->ipv6), val); +} + +/** + * flow_check_cf_bmk_values - check value/bitmask part of flowspec component + * @fb: flow builder instance + * @neg: negation operand + * @val: value from value/mask pair + * @mask: bitmap mask from value/mask pair + * + * This function checks value/bitmask pair. If some problem will appear, the + * function calls cf_error() function with a textual description of reason + * to failing of validation. + */ +static void +flow_check_cf_bmk_values(struct flow_builder *fb, u8 neg, u32 val, u32 mask) +{ + flow_check_cf_value_length(fb, val); + flow_check_cf_value_length(fb, mask); + + if (neg && !(val == 0 || val == mask)) + cf_error("For negation, value must be zero or bitmask"); + + if ((fb->this_type == FLOW_TYPE_TCP_FLAGS) && (mask & 0xf000)) + cf_error("Invalid mask 0x%x, must not exceed 0xfff", mask); + + if ((fb->this_type == FLOW_TYPE_FRAGMENT) && fb->ipv6 && (mask & 0x01)) + cf_error("Invalid mask 0x%x, bit 0 must be 0", mask); + + if (val & ~mask) + cf_error("Value 0x%x outside bitmask 0x%x", val, mask); +} + +/** + * flow4_validate_cf - validate flowspec data structure &net_addr_flow4 in parsing time + * @f: flowspec data structure &net_addr_flow4 + * + * Check if @f is valid flowspec data structure. Can call cf_error() function + * with a textual description of reason to failing of validation. + */ +static void +flow4_validate_cf(net_addr_flow4 *f) +{ + enum flow_validated_state r = flow4_validate(flow4_first_part(f), flow_read_length(f->data)); + + if (r != FLOW_ST_VALID) + cf_error("Invalid flow route: %s", flow_validated_state_str(r)); +} + +/** + * flow6_validate_cf - validate flowspec data structure &net_addr_flow6 in parsing time + * @f: flowspec data structure &net_addr_flow6 + * + * Check if @f is valid flowspec data structure. Can call cf_error() function + * with a textual description of reason to failing of validation. + */ +static void +flow6_validate_cf(net_addr_flow6 *f) +{ + enum flow_validated_state r = flow6_validate(flow6_first_part(f), flow_read_length(f->data)); + + if (r != FLOW_ST_VALID) + cf_error("Invalid flow route: %s", flow_validated_state_str(r)); +} + CF_DECLS diff --git a/configure.ac b/configure.ac index f34275ac5..7d09d3a01 100644 --- a/configure.ac +++ b/configure.ac @@ -30,6 +30,12 @@ AC_ARG_ENABLE([debug-expensive], [enable_debug_expensive=no] ) +AC_ARG_ENABLE([debug-allocator], + [AS_HELP_STRING([--enable-debug-allocator], [enable internal memory allocator journal (implies --enable-debug) @<:@no@:>@])], + [], + [enable_debug_expensive=no] +) + AC_ARG_ENABLE([memcheck], [AS_HELP_STRING([--enable-memcheck], [check memory allocations when debugging @<:@yes@:>@])], [], @@ -78,6 +84,10 @@ AC_ARG_VAR([FLEX], [location of the Flex program]) AC_ARG_VAR([BISON], [location of the Bison program]) AC_ARG_VAR([M4], [location of the M4 program]) +if test "$enable_debug_allocator" = yes; then + enable_debug=yes +fi + if test "$enable_debug_expensive" = yes; then enable_debug=yes fi @@ -124,6 +134,8 @@ if test -z "$GCC" ; then AC_MSG_ERROR([This program requires the GNU C Compiler.]) fi +BIRD_COMPILER_VENDOR + BIRD_CHECK_THREAD_LOCAL if test "$bird_cv_thread_local" = no ; then AC_MSG_ERROR([This program requires thread local storage.]) @@ -135,7 +147,7 @@ BIRD_CHECK_PTHREADS if test "$bird_cv_lib_pthreads" = yes ; then CFLAGS="$CFLAGS -pthread" - LDFLAGS="$LDFLAGS -pthread" + COMMON_LIBS="$COMMON_LIBS -pthread" else AC_MSG_ERROR([POSIX threads not available.]) fi @@ -150,12 +162,18 @@ if test "$bird_cflags_default" = yes ; then BIRD_CHECK_GCC_OPTION([bird_cv_c_option_werror_implicit_function_declaration], [-Werror=implicit-function-declaration], [-Wall -Wextra]) if test "$enable_debug" = no; then - BIRD_CHECK_LTO + LTO_CFLAGS=-flto + AS_CASE(${bird_cv_compiler_vendor}, + gnu,LTO_LDFLAGS="-flto=jobserver", + llvm,LTO_LDFLAGS="-flto", + unknown,LTO_LDFLAGS="-flto", + AC_MSG_ERROR([Compiler vendor check failed for LTO: got ${bird_cv_compiler_vendor}])) + BIRD_CHECK_LTO(${LTO_CFLAGS}, ${LTO_LDFLAGS}) fi if test "$bird_cv_c_lto" = yes; then - CFLAGS="$CFLAGS -flto" - LDFLAGS="$LDFLAGS -flto=4 -g" + CFLAGS="$CFLAGS $LTO_CFLAGS" + LDFLAGS="$LDFLAGS $LTO_LDFLAGS -g" else LDFLAGS="$LDFLAGS -g" fi @@ -174,9 +192,13 @@ AC_MSG_RESULT([$CFLAGS]) AC_MSG_CHECKING([LDFLAGS]) AC_MSG_RESULT([$LDFLAGS]) +DAEMON_LIBS="${DAEMON_LIBS} ${LIBS}" +AC_SUBST(DAEMON_LIBS) +AC_SUBST(COMMON_LIBS) + AC_PROG_CPP AC_PROG_INSTALL -AC_PROG_RANLIB + AC_CHECK_PROG([FLEX], [flex], [flex]) AC_CHECK_PROG([BISON], [bison], [bison]) AC_CHECK_PROGS([M4], [gm4 m4]) @@ -261,6 +283,8 @@ sysdep_dirs="`sed <$sysdesc '/^Link: /!d;s/^Link: \(.*\)$/\1/' | tr '\012' ' '`" AC_MSG_RESULT([$sysdep_dirs]) AC_SUBST([sysdep_dirs]) +AC_CHECK_FUNCS([pipe2]) + if test "$with_iproutedir" = no ; then with_iproutedir= ; fi if test -n "$given_iproutedir" @@ -270,16 +294,13 @@ fi AC_SUBST([iproutedir]) -DAEMON_LIBS= -AC_SUBST(DAEMON_LIBS) - if test "$enable_libssh" != no ; then AC_CHECK_HEADER([libssh/libssh.h], [true], [fail=yes], [ ]) AC_CHECK_LIB([ssh], [ssh_connect], [true], [fail=yes]) if test "$fail" != yes ; then AC_DEFINE([HAVE_LIBSSH], [1], [Define to 1 if you have the `ssh' library (-lssh).]) - DAEMON_LIBS="-lssh $DAEMON_LIBS" + COMMON_LIBS="-lssh $COMMON_LIBS" enable_libssh=yes else if test "$enable_libssh" = yes ; then @@ -442,6 +463,10 @@ if test "$enable_debug" = yes ; then if test "$enable_debug_expensive" = yes ; then AC_DEFINE([ENABLE_EXPENSIVE_CHECKS], [1], [Define to 1 if you want to run expensive consistency checks.]) fi + + if test "$enable_debug_allocator" = yes; then + AC_DEFINE([DEBUG_ALLOCATOR], [1], [Define to 1 if you want to store journals from memory allocations.]) + fi fi if test "$enable_compact_tries" = yes ; then diff --git a/doc/bird.sgml b/doc/bird.sgml index 11a124943..d2ddbe78e 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -781,6 +781,38 @@ which contain the following options: the worker group thread count to that number, and the express group thread count to one. This setting is deprecated and may disappear in some future version. +Global performance options +