You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.6 KiB

  1. From dc397e4c0adc13982fc5d83a1afc42178708f4a5 Mon Sep 17 00:00:00 2001
  2. From: Renato Westphal <renato@opensourcerouting.org>
  3. Date: Fri, 3 Apr 2020 20:10:04 -0300
  4. Subject: [PATCH] lib: consolidate flexible array hack in a single place
  5. Old gcc versions (< 5.x) have a bug that prevents C99 flexible
  6. arrays from working properly on shared libraries.
  7. We already have a hack in place to work around this problem, but it
  8. needs to be replicated in every declaration of a frr_yang_module_info
  9. variable within libfrr. This clearly isn't a good solution if we
  10. consider that many more libfrr YANG modules are about to come in
  11. the future.
  12. This commit introduces a different workaround that operates within
  13. the northbound layer itself, such that implementers of libfrr YANG
  14. modules won't need to worry about this problem anymore.
  15. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
  16. ---
  17. lib/if.c | 24 ------------------------
  18. lib/northbound.c | 7 +++++++
  19. lib/northbound.h | 11 +++++++++++
  20. lib/routemap_northbound.c | 25 -------------------------
  21. 4 files changed, 18 insertions(+), 49 deletions(-)
  22. diff --git a/lib/if.c b/lib/if.c
  23. index dabf66799d..24b103b3ff 100644
  24. --- a/lib/if.c
  25. +++ b/lib/if.c
  26. @@ -1657,31 +1657,7 @@ static int lib_interface_description_destroy(enum nb_event event,
  27. /* clang-format off */
  28. -#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
  29. -/* gcc versions before 5.x miscalculate the size for structs with variable
  30. - * length arrays (they just count it as size 0)
  31. - */
  32. -struct frr_yang_module_info_size3 {
  33. - /* YANG module name. */
  34. - const char *name;
  35. -
  36. - /* Northbound callbacks. */
  37. - const struct {
  38. - /* Data path of this YANG node. */
  39. - const char *xpath;
  40. -
  41. - /* Callbacks implemented for this node. */
  42. - struct nb_callbacks cbs;
  43. -
  44. - /* Priority - lower priorities are processed first. */
  45. - uint32_t priority;
  46. - } nodes[3];
  47. -};
  48. -
  49. -const struct frr_yang_module_info_size3 frr_interface_info_size3 asm("frr_interface_info") = {
  50. -#else
  51. const struct frr_yang_module_info frr_interface_info = {
  52. -#endif
  53. .name = "frr-interface",
  54. .nodes = {
  55. {
  56. diff --git a/lib/northbound.c b/lib/northbound.c
  57. index cebedcff09..85e723d7cf 100644
  58. --- a/lib/northbound.c
  59. +++ b/lib/northbound.c
  60. @@ -1866,6 +1866,13 @@ static void nb_load_callbacks(const struct frr_yang_module_info *module)
  61. struct nb_node *nb_node;
  62. uint32_t priority;
  63. + if (i > YANG_MODULE_MAX_NODES) {
  64. + zlog_err(
  65. + "%s: %s.yang has more than %u nodes. Please increase YANG_MODULE_MAX_NODES to fix this problem.",
  66. + __func__, module->name, YANG_MODULE_MAX_NODES);
  67. + exit(1);
  68. + }
  69. +
  70. nb_node = nb_node_find(module->nodes[i].xpath);
  71. if (!nb_node) {
  72. flog_warn(EC_LIB_YANG_UNKNOWN_DATA_PATH,
  73. diff --git a/lib/northbound.h b/lib/northbound.h
  74. index 76a11e518c..19a2ba0865 100644
  75. --- a/lib/northbound.h
  76. +++ b/lib/northbound.h
  77. @@ -403,6 +403,13 @@ struct nb_node {
  78. /* The YANG list doesn't contain key leafs. */
  79. #define F_NB_NODE_KEYLESS_LIST 0x02
  80. +/*
  81. + * HACK: old gcc versions (< 5.x) have a bug that prevents C99 flexible arrays
  82. + * from working properly on shared libraries. For those compilers, use a fixed
  83. + * size array to work around the problem.
  84. + */
  85. +#define YANG_MODULE_MAX_NODES 1024
  86. +
  87. struct frr_yang_module_info {
  88. /* YANG module name. */
  89. const char *name;
  90. @@ -417,7 +424,11 @@ struct frr_yang_module_info {
  91. /* Priority - lower priorities are processed first. */
  92. uint32_t priority;
  93. +#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
  94. + } nodes[YANG_MODULE_MAX_NODES + 1];
  95. +#else
  96. } nodes[];
  97. +#endif
  98. };
  99. /* Northbound error codes. */
  100. diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c
  101. index 69cebbd2a1..dd4cbd7d99 100644
  102. --- a/lib/routemap_northbound.c
  103. +++ b/lib/routemap_northbound.c
  104. @@ -1221,32 +1221,7 @@ lib_route_map_entry_set_action_tag_destroy(enum nb_event event,
  105. }
  106. /* clang-format off */
  107. -#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
  108. -/*
  109. - * gcc versions before 5.x miscalculate the size for structs with variable
  110. - * length arrays (they just count it as size 0)
  111. - */
  112. -struct frr_yang_module_info_sizen {
  113. - /* YANG module name. */
  114. - const char *name;
  115. -
  116. - /* Northbound callbacks. */
  117. - const struct {
  118. - /* Data path of this YANG node. */
  119. - const char *xpath;
  120. -
  121. - /* Callbacks implemented for this node. */
  122. - struct nb_callbacks cbs;
  123. -
  124. - /* Priority - lower priorities are processed first. */
  125. - uint32_t priority;
  126. - } nodes[28];
  127. -};
  128. -
  129. -const struct frr_yang_module_info_sizen frr_route_map_info_sizen asm("frr_route_map_info") = {
  130. -#else
  131. const struct frr_yang_module_info frr_route_map_info = {
  132. -#endif
  133. .name = "frr-route-map",
  134. .nodes = {
  135. {