From dc397e4c0adc13982fc5d83a1afc42178708f4a5 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 3 Apr 2020 20:10:04 -0300 Subject: [PATCH] lib: consolidate flexible array hack in a single place Old gcc versions (< 5.x) have a bug that prevents C99 flexible arrays from working properly on shared libraries. We already have a hack in place to work around this problem, but it needs to be replicated in every declaration of a frr_yang_module_info variable within libfrr. This clearly isn't a good solution if we consider that many more libfrr YANG modules are about to come in the future. This commit introduces a different workaround that operates within the northbound layer itself, such that implementers of libfrr YANG modules won't need to worry about this problem anymore. Signed-off-by: Renato Westphal --- lib/if.c | 24 ------------------------ lib/northbound.c | 7 +++++++ lib/northbound.h | 11 +++++++++++ lib/routemap_northbound.c | 25 ------------------------- 4 files changed, 18 insertions(+), 49 deletions(-) diff --git a/lib/if.c b/lib/if.c index dabf66799d..24b103b3ff 100644 --- a/lib/if.c +++ b/lib/if.c @@ -1657,31 +1657,7 @@ static int lib_interface_description_destroy(enum nb_event event, /* clang-format off */ -#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__) -/* gcc versions before 5.x miscalculate the size for structs with variable - * length arrays (they just count it as size 0) - */ -struct frr_yang_module_info_size3 { - /* YANG module name. */ - const char *name; - - /* Northbound callbacks. */ - const struct { - /* Data path of this YANG node. */ - const char *xpath; - - /* Callbacks implemented for this node. */ - struct nb_callbacks cbs; - - /* Priority - lower priorities are processed first. */ - uint32_t priority; - } nodes[3]; -}; - -const struct frr_yang_module_info_size3 frr_interface_info_size3 asm("frr_interface_info") = { -#else const struct frr_yang_module_info frr_interface_info = { -#endif .name = "frr-interface", .nodes = { { diff --git a/lib/northbound.c b/lib/northbound.c index cebedcff09..85e723d7cf 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -1866,6 +1866,13 @@ static void nb_load_callbacks(const struct frr_yang_module_info *module) struct nb_node *nb_node; uint32_t priority; + if (i > YANG_MODULE_MAX_NODES) { + zlog_err( + "%s: %s.yang has more than %u nodes. Please increase YANG_MODULE_MAX_NODES to fix this problem.", + __func__, module->name, YANG_MODULE_MAX_NODES); + exit(1); + } + nb_node = nb_node_find(module->nodes[i].xpath); if (!nb_node) { flog_warn(EC_LIB_YANG_UNKNOWN_DATA_PATH, diff --git a/lib/northbound.h b/lib/northbound.h index 76a11e518c..19a2ba0865 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -403,6 +403,13 @@ struct nb_node { /* The YANG list doesn't contain key leafs. */ #define F_NB_NODE_KEYLESS_LIST 0x02 +/* + * HACK: old gcc versions (< 5.x) have a bug that prevents C99 flexible arrays + * from working properly on shared libraries. For those compilers, use a fixed + * size array to work around the problem. + */ +#define YANG_MODULE_MAX_NODES 1024 + struct frr_yang_module_info { /* YANG module name. */ const char *name; @@ -417,7 +424,11 @@ struct frr_yang_module_info { /* Priority - lower priorities are processed first. */ uint32_t priority; +#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__) + } nodes[YANG_MODULE_MAX_NODES + 1]; +#else } nodes[]; +#endif }; /* Northbound error codes. */ diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c index 69cebbd2a1..dd4cbd7d99 100644 --- a/lib/routemap_northbound.c +++ b/lib/routemap_northbound.c @@ -1221,32 +1221,7 @@ lib_route_map_entry_set_action_tag_destroy(enum nb_event event, } /* clang-format off */ -#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__) -/* - * gcc versions before 5.x miscalculate the size for structs with variable - * length arrays (they just count it as size 0) - */ -struct frr_yang_module_info_sizen { - /* YANG module name. */ - const char *name; - - /* Northbound callbacks. */ - const struct { - /* Data path of this YANG node. */ - const char *xpath; - - /* Callbacks implemented for this node. */ - struct nb_callbacks cbs; - - /* Priority - lower priorities are processed first. */ - uint32_t priority; - } nodes[28]; -}; - -const struct frr_yang_module_info_sizen frr_route_map_info_sizen asm("frr_route_map_info") = { -#else const struct frr_yang_module_info frr_route_map_info = { -#endif .name = "frr-route-map", .nodes = { {