]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: consolidate flexible array hack in a single place
authorRenato Westphal <renato@opensourcerouting.org>
Fri, 3 Apr 2020 23:10:04 +0000 (20:10 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Sat, 4 Apr 2020 01:34:55 +0000 (22:34 -0300)
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 <renato@opensourcerouting.org>
lib/if.c
lib/northbound.c
lib/northbound.h
lib/routemap_northbound.c

index dabf66799d68745d37b4c6b39a332805bfe02fee..24b103b3ffabd23a188a0f2aab199e011b18b0ed 100644 (file)
--- 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 = {
                {
index cebedcff097712c200d98dad29f025046819a180..85e723d7cf4fc9aafbee1e0936718fc7bee10308 100644 (file)
@@ -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,
index 76a11e518cc02806dd79786da86f9f38712434b8..19a2ba0865467ed093acc754b780e0a38df71a9e 100644 (file)
@@ -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. */
index 69cebbd2a1e231b0f2812bff96d9c00f17ccffef..dd4cbd7d99313ba232e5c025363a73366c7c3121 100644 (file)
@@ -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 = {
                {