From 48875628bf6bec0f6b7058748d534cdd90a41032 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Mon, 15 Jul 2024 02:26:52 +0300 Subject: [PATCH] [meta][sai] Move extensions SAI and API to 0x20000000 range (#2028) * [meta][sai] Move extensions SAI and API to 0x20000000 range To make this binary backward comparible for extension enums, instead of starting form _ATTR_END and prevent enum shift each time new attribute is added * [meta] Update saisanitycheck to not use object type as index Since we will move object type extensions to separate range we will need to update many shorcuts taken by sisanitych check when it was using obejct type as index to fast access arrays Signed-off-by: siqbal1986 --- experimental/saiextensions.h | 2 +- experimental/saiportextensions.h | 4 +- experimental/saiswitchextensions.h | 2 +- experimental/saitypesextensions.h | 2 +- inc/sai.h | 9 +- inc/saiport.h | 10 +- inc/saiswitch.h | 5 +- inc/saitypes.h | 6 +- meta/parse.pl | 13 +- meta/saidepgraphgen.cpp | 38 ++- meta/saimetadatautils.c | 85 ++++-- meta/saimetadatautils.h | 12 + meta/saisanitycheck.c | 448 +++++++++++++++++++---------- meta/saiserializetest.c | 2 +- meta/test.pm | 64 +++-- 15 files changed, 452 insertions(+), 250 deletions(-) diff --git a/experimental/saiextensions.h b/experimental/saiextensions.h index 802976d88..7e96229c5 100644 --- a/experimental/saiextensions.h +++ b/experimental/saiextensions.h @@ -55,7 +55,7 @@ */ typedef enum _sai_api_extensions_t { - SAI_API_EXTENSIONS_RANGE_START = SAI_API_MAX, + SAI_API_EXTENSIONS_RANGE_START = SAI_API_EXTENSIONS_RANGE_BASE, SAI_API_BMTOR = SAI_API_EXTENSIONS_RANGE_START, diff --git a/experimental/saiportextensions.h b/experimental/saiportextensions.h index 01c30665f..22c25d065 100644 --- a/experimental/saiportextensions.h +++ b/experimental/saiportextensions.h @@ -35,7 +35,7 @@ */ typedef enum _sai_port_attr_extensions_t { - SAI_PORT_ATTR_EXTENSIONS_RANGE_START = SAI_PORT_ATTR_END, + SAI_PORT_ATTR_EXTENSIONS_RANGE_START = SAI_PORT_ATTR_EXTENSIONS_RANGE_BASE, /* Add new experimental port attributes above this line */ @@ -50,7 +50,7 @@ typedef enum _sai_port_attr_extensions_t */ typedef enum _sai_port_stat_extensions_t { - SAI_PORT_STAT_EXTENSIONS_RANGE_START = SAI_PORT_STAT_END, + SAI_PORT_STAT_EXTENSIONS_RANGE_START = SAI_PORT_STAT_EXTENSIONS_RANGE_BASE, /** DASH port LB_FAST_PATH_ICMP_IN_BYTES stat count */ SAI_PORT_STAT_LB_FAST_PATH_ICMP_IN_BYTES = SAI_PORT_STAT_EXTENSIONS_RANGE_START, diff --git a/experimental/saiswitchextensions.h b/experimental/saiswitchextensions.h index df6765833..afa6e0e4d 100644 --- a/experimental/saiswitchextensions.h +++ b/experimental/saiswitchextensions.h @@ -132,7 +132,7 @@ typedef void (*sai_ha_scope_event_notification_fn)( */ typedef enum _sai_switch_attr_extensions_t { - SAI_SWITCH_ATTR_EXTENSIONS_RANGE_START = SAI_SWITCH_ATTR_END, + SAI_SWITCH_ATTR_EXTENSIONS_RANGE_START = SAI_SWITCH_ATTR_EXTENSIONS_RANGE_BASE, /** * @brief Maximum number of meter buckets per ENI. diff --git a/experimental/saitypesextensions.h b/experimental/saitypesextensions.h index ee2f52066..578ab74b4 100644 --- a/experimental/saitypesextensions.h +++ b/experimental/saitypesextensions.h @@ -34,7 +34,7 @@ */ typedef enum _sai_object_type_extensions_t { - SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START = SAI_OBJECT_TYPE_MAX, + SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START = SAI_OBJECT_TYPE_EXTENSIONS_RANGE_BASE, SAI_OBJECT_TYPE_TABLE_BITMAP_CLASSIFICATION_ENTRY = SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START, diff --git a/inc/sai.h b/inc/sai.h index c612c6173..8ce7039bb 100644 --- a/inc/sai.h +++ b/inc/sai.h @@ -152,11 +152,10 @@ typedef enum _sai_api_t SAI_API_ICMP_ECHO = 52, /**< sai_icmp_echo_api_t */ SAI_API_MAX, /**< total number of APIs */ - /** Custom range base value */ - SAI_API_CUSTOM_RANGE_START = 256, - - /** End of custom range base */ - SAI_API_CUSTOM_RANGE_END + /** + * @brief Extensions range base + */ + SAI_API_EXTENSIONS_RANGE_BASE = 0x20000000, } sai_api_t; /** diff --git a/inc/saiport.h b/inc/saiport.h index c2e9db2a1..5d36705c9 100644 --- a/inc/saiport.h +++ b/inc/saiport.h @@ -2529,7 +2529,10 @@ typedef enum _sai_port_attr_t SAI_PORT_ATTR_CUSTOM_RANGE_START = 0x10000000, /** End of custom range base */ - SAI_PORT_ATTR_CUSTOM_RANGE_END + SAI_PORT_ATTR_CUSTOM_RANGE_END, + + /** Extensions range base */ + SAI_PORT_ATTR_EXTENSIONS_RANGE_BASE = 0x20000000 } sai_port_attr_t; @@ -3256,7 +3259,10 @@ typedef enum _sai_port_stat_t SAI_PORT_STAT_OUT_DROP_REASON_RANGE_END = 0x00002fff, /** Port stat range end */ - SAI_PORT_STAT_END + SAI_PORT_STAT_END, + + /** Extensions range base */ + SAI_PORT_STAT_EXTENSIONS_RANGE_BASE = 0x20000000 } sai_port_stat_t; diff --git a/inc/saiswitch.h b/inc/saiswitch.h index 4883b116e..523cb3c4d 100644 --- a/inc/saiswitch.h +++ b/inc/saiswitch.h @@ -3057,7 +3057,10 @@ typedef enum _sai_switch_attr_t SAI_SWITCH_ATTR_CUSTOM_RANGE_START = 0x10000000, /** End of custom range base */ - SAI_SWITCH_ATTR_CUSTOM_RANGE_END + SAI_SWITCH_ATTR_CUSTOM_RANGE_END, + + /** Extensions range base */ + SAI_SWITCH_ATTR_EXTENSIONS_RANGE_BASE = 0x20000000 } sai_switch_attr_t; diff --git a/inc/saitypes.h b/inc/saitypes.h index 7da5c09cb..f34c30c97 100644 --- a/inc/saitypes.h +++ b/inc/saitypes.h @@ -303,11 +303,7 @@ typedef enum _sai_object_type_t /** Must remain in last position */ SAI_OBJECT_TYPE_MAX, - /** Custom range base value */ - SAI_OBJECT_TYPE_CUSTOM_RANGE_START = 256, - - /** End of custom range base */ - SAI_OBJECT_TYPE_CUSTOM_RANGE_END + SAI_OBJECT_TYPE_EXTENSIONS_RANGE_BASE = 0x20000000, } sai_object_type_t; typedef struct _sai_u8_list_t diff --git a/meta/parse.pl b/meta/parse.pl index 55b9d0c74..af3d5f69b 100755 --- a/meta/parse.pl +++ b/meta/parse.pl @@ -2413,7 +2413,7 @@ sub ProcessSingleObjectType WriteSource ".isresourcetype = $isresourcetype,"; WriteSource ".isdeprecated = $isdeprecated,"; WriteSource ".isconditionrelaxed = $isrelaxed,"; - WriteSource ".iscustom = $attr >= 0x10000000"; + WriteSource ".iscustom = ($attr >= 0x10000000) && ($attr < 0x20000000)"; WriteSource "};"; @@ -2542,7 +2542,8 @@ sub CreateMetadataForAttributes WriteSource "};"; } - WriteHeader "extern const sai_attr_metadata_t* const* const sai_metadata_attr_by_object_type[];"; + # This is disabled since it's object type can't be used as index any more + # WriteHeader "extern const sai_attr_metadata_t* const* const sai_metadata_attr_by_object_type[];"; WriteSource "const sai_attr_metadata_t* const* const sai_metadata_attr_by_object_type[] = {"; for my $ot (@objects) @@ -2565,10 +2566,6 @@ sub CreateMetadataForAttributes WriteHeader "extern const size_t sai_metadata_attr_by_object_type_count;"; WriteSource "const size_t sai_metadata_attr_by_object_type_count = $count;"; - - WriteSectionComment "Define SAI_OBJECT_TYPE_EXTENSIONS_MAX"; - - WriteHeader "#define SAI_OBJECT_TYPE_EXTENSIONS_MAX ((sai_object_type_t)$count)"; } sub CreateEnumHelperMethod @@ -3246,10 +3243,6 @@ sub CreateApisStruct WriteHeader "} sai_apis_t;"; my $count = scalar @apis; - - WriteSectionComment "Define SAI_API_EXTENSIONS_MAX"; - - WriteHeader "#define SAI_API_EXTENSIONS_MAX ((sai_api_t)$count)"; } sub CreateGlobalApis diff --git a/meta/saidepgraphgen.cpp b/meta/saidepgraphgen.cpp index 781c080ca..86cb70778 100644 --- a/meta/saidepgraphgen.cpp +++ b/meta/saidepgraphgen.cpp @@ -34,7 +34,7 @@ extern "C" { } // node name -#define NN(x) (sai_metadata_enum_sai_object_type_t.valuesshortnames[(x)]) +#define NN(x) (sai_metadata_get_enum_value_short_name(&sai_metadata_enum_sai_object_type_t,(x))) static std::set source; static std::set target; @@ -132,19 +132,19 @@ static void process_object_type_attributes( static void process_object_types() { - for (int i = 0; sai_metadata_attr_by_object_type[i] != NULL; ++i) + for (int idx = 1; sai_metadata_all_object_type_infos[idx]; ++idx) { - const sai_attr_metadata_t* const* const meta = sai_metadata_attr_by_object_type[i]; + const sai_attr_metadata_t* const* const meta = sai_metadata_all_object_type_infos[idx]->attrmetadata; - process_object_type_attributes(meta, (sai_object_type_t)i); + process_object_type_attributes(meta, sai_metadata_all_object_type_infos[idx]->objecttype); } } static void process_colors() { - for (int i = 0; sai_metadata_attr_by_object_type[i] != NULL; ++i) + for (int idx = 1; sai_metadata_all_object_type_infos[idx]; ++idx) { - sai_object_type_t ot = (sai_object_type_t)i; + sai_object_type_t ot = sai_metadata_all_object_type_infos[idx]->objecttype; bool is_source = source.find(ot) != source.end(); bool is_target = target.find(ot) != target.end(); @@ -176,23 +176,21 @@ static void process_colors() } } - size_t max = show_extensions ? SAI_OBJECT_TYPE_EXTENSIONS_MAX : SAI_OBJECT_TYPE_MAX; - - for (size_t i = SAI_OBJECT_TYPE_NULL; i < max; ++i) + for (size_t idx = 1 ; sai_metadata_all_object_type_infos[idx]; ++idx) { - const sai_object_type_info_t* oi = sai_metadata_all_object_type_infos[i]; + const sai_object_type_info_t* oi = sai_metadata_all_object_type_infos[idx]; - if (oi == NULL) + if (!oi->isnonobjectid) { continue; } - if (!oi->isnonobjectid) + if (oi->objecttype >= SAI_OBJECT_TYPE_MAX && !show_extensions) { continue; } - std::cout << NN(i) << " [color=plum, shape = rect];\n"; + std::cout << NN(oi->objecttype) << " [color=plum, shape = rect];\n"; } } @@ -203,18 +201,16 @@ static void process_nonobjectid_connections() { const char* c = " [color=\"0.650 0.700 0.700\", style = dashed, penwidth=2];\n"; - size_t max = show_extensions ? SAI_OBJECT_TYPE_EXTENSIONS_MAX : SAI_OBJECT_TYPE_MAX; - - for (size_t i = SAI_OBJECT_TYPE_NULL; i < max; ++i) + for (size_t idx = 1 ; sai_metadata_all_object_type_infos[idx]; ++idx) { - const sai_object_type_info_t* oi = sai_metadata_all_object_type_infos[i]; + const sai_object_type_info_t* oi = sai_metadata_all_object_type_infos[idx]; - if (oi == NULL) + if (!oi->isnonobjectid) { continue; } - if (!oi->isnonobjectid) + if (oi->objecttype >= SAI_OBJECT_TYPE_MAX && !show_extensions) { continue; } @@ -236,12 +232,12 @@ static void process_nonobjectid_connections() continue; } - std::cout << NN(ot) << " -> " << NN((sai_object_type_t)i) << c; + std::cout << NN(ot) << " -> " << NN(oi->objecttype) << c; } } else if (sm->isvlan) { - std::cout << NN(SAI_OBJECT_TYPE_VLAN) << " -> " << NN((sai_object_type_t)i) << c; + std::cout << NN(SAI_OBJECT_TYPE_VLAN) << " -> " << NN(oi->objecttype) << c; } } } diff --git a/meta/saimetadatautils.c b/meta/saimetadatautils.c index a37a051ee..c82c717a5 100644 --- a/meta/saimetadatautils.c +++ b/meta/saimetadatautils.c @@ -78,32 +78,34 @@ const sai_attr_metadata_t* sai_metadata_get_attr_metadata( _In_ sai_object_type_t objecttype, _In_ sai_attr_id_t attrid) { - if (sai_metadata_is_object_type_valid(objecttype)) + const sai_object_type_info_t* oi = sai_metadata_get_object_type_info(objecttype); + + if (oi == NULL) { - const sai_attr_metadata_t* const* const md = sai_metadata_attr_by_object_type[objecttype]; + return NULL; + } - /* - * Most object attributes are not flags, so we can use direct index to - * find attribute metadata, this should speed up search. - */ + const sai_attr_metadata_t* const* const md = oi->attrmetadata; - const sai_object_type_info_t* oi = sai_metadata_all_object_type_infos[objecttype]; + /* + * Most object attributes are not flags, so we can use direct index to + * find attribute metadata, this should speed up search. + */ - if (!oi->enummetadata->containsflags && attrid < oi->attridend) - { - return md[attrid]; - } + if (!oi->enummetadata->containsflags && attrid < oi->attridend) + { + return md[attrid]; + } - /* otherwise search one by one */ + /* otherwise search one by one */ - size_t index = 0; + size_t index = 0; - for (; md[index] != NULL; index++) + for (; md[index] != NULL; index++) + { + if (md[index]->attrid == attrid) { - if (md[index]->attrid == attrid) - { - return md[index]; - } + return md[index]; } } @@ -227,21 +229,16 @@ const sai_attr_metadata_t* sai_metadata_get_ignored_attr_metadata_by_attr_id_nam return NULL; } - sai_object_type_t ot; + int idx = 1; /* * Since we don't have list of ignored attributes, enumerate all objects * and attribute enums to find ignored values. */ - for (ot = SAI_OBJECT_TYPE_NULL; ot < SAI_OBJECT_TYPE_EXTENSIONS_MAX; ot++) + for (; sai_metadata_all_object_type_infos[idx]; idx++) { - const sai_object_type_info_t* oti = sai_metadata_get_object_type_info(ot); - - if (oti == NULL) - continue; - - const sai_enum_metadata_t* em = oti->enummetadata; + const sai_enum_metadata_t* em = sai_metadata_all_object_type_infos[idx]->enummetadata; if (em->ignorevaluesnames) { @@ -284,6 +281,28 @@ const char* sai_metadata_get_enum_value_name( return NULL; } +const char* sai_metadata_get_enum_value_short_name( + _In_ const sai_enum_metadata_t* metadata, + _In_ int value) +{ + if (metadata == NULL) + { + return NULL; + } + + size_t i = 0; + + for (; i < metadata->valuescount; ++i) + { + if (metadata->values[i] == value) + { + return metadata->valuesshortnames[i]; + } + } + + return NULL; +} + const sai_attribute_t* sai_metadata_get_attr_by_id( _In_ sai_attr_id_t id, _In_ uint32_t attr_count, @@ -310,11 +329,21 @@ const sai_attribute_t* sai_metadata_get_attr_by_id( const sai_object_type_info_t* sai_metadata_get_object_type_info( _In_ sai_object_type_t object_type) { - if (sai_metadata_is_object_type_valid(object_type)) + if (object_type >= SAI_OBJECT_TYPE_NULL && object_type < SAI_OBJECT_TYPE_MAX) { return sai_metadata_all_object_type_infos[object_type]; } + int idx = 1; + + for (; sai_metadata_all_object_type_infos[idx]; idx++) + { + if (sai_metadata_all_object_type_infos[idx]->objecttype == object_type) + { + return sai_metadata_all_object_type_infos[idx]; + } + } + return NULL; } @@ -334,7 +363,7 @@ bool sai_metadata_is_object_type_oid( bool sai_metadata_is_object_type_valid( _In_ sai_object_type_t object_type) { - return object_type > SAI_OBJECT_TYPE_NULL && object_type < SAI_OBJECT_TYPE_EXTENSIONS_MAX; + return sai_metadata_get_object_type_info(object_type) != NULL; } static bool sai_metadata_is_condition_value_eq( diff --git a/meta/saimetadatautils.h b/meta/saimetadatautils.h index 41fa76adf..dd651c68d 100644 --- a/meta/saimetadatautils.h +++ b/meta/saimetadatautils.h @@ -113,6 +113,18 @@ extern const char* sai_metadata_get_enum_value_name( _In_ const sai_enum_metadata_t *metadata, _In_ int value); +/** + * @brief Gets short string representation of enum value + * + * @param[in] metadata Enum metadata + * @param[in] value Enum value to be converted to string + * + * @return Short string representation of enum value or NULL if value was not found + */ +extern const char* sai_metadata_get_enum_value_short_name( + _In_ const sai_enum_metadata_t *metadata, + _In_ int value); + /** * @brief Gets attribute from attribute list by attribute id. * diff --git a/meta/saisanitycheck.c b/meta/saisanitycheck.c index 9b6c59586..2a63b64e6 100644 --- a/meta/saisanitycheck.c +++ b/meta/saisanitycheck.c @@ -93,6 +93,9 @@ defined_attr_t* defined_attributes = NULL; /* custom ranges start are the same for all objects */ #define CUSTOM_ATTR_RANGE_START SAI_PORT_ATTR_CUSTOM_RANGE_START +#define EXTENSION_RANGE_START (0x20000000) +#define EXTENSION_OBJECT_TYPE_COUNT (SAI_OBJECT_TYPE_EXTENSIONS_RANGE_END - SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START) +#define TOTAL_OBJECT_TYPE_COUNT (EXTENSION_OBJECT_TYPE_COUNT + SAI_OBJECT_TYPE_MAX) bool is_extensions_enum( _In_ const sai_enum_metadata_t* emd) @@ -108,7 +111,7 @@ void check_all_enums_name_pointers() size_t i = 0; - META_ASSERT_TRUE(sai_metadata_all_enums_count > 100, "we need to have some enums"); + META_ASSERT_TRUE(sai_metadata_all_enums_count > 300, "we need to have some enums"); for (; i < sai_metadata_all_enums_count; ++i) { @@ -218,7 +221,17 @@ void check_all_enums_values() * not flags, attribute value can't be used as array index. */ - META_ENUM_LOG_WARN(emd, "contains custom range attibutes"); + META_ENUM_LOG_WARN(emd, "contains custom range attributes"); + } + else if (value == EXTENSION_RANGE_START) + { + /* + * Object contains extensions attributes, they still needs + * to be increasing by 1 but since those are not flags, + * attribute value can't be used as array index. + */ + + META_ENUM_LOG_WARN(emd, "contains extensions range attributes"); } else { @@ -237,10 +250,14 @@ void check_all_enums_values() last = emd->values[j]; - if (value >= CUSTOM_ATTR_RANGE_START && value < (2 * CUSTOM_ATTR_RANGE_START)) + if (value >= CUSTOM_ATTR_RANGE_START && value < EXTENSION_RANGE_START) { /* value is in custom range */ } + else if (value >= EXTENSION_RANGE_START) + { + /* value is in extensions range */ + } else { META_ASSERT_TRUE(value < 0x10000, "enum value is too big, range?"); @@ -357,30 +374,58 @@ void check_object_type() int value = sai_metadata_enum_sai_object_type_t.values[i]; - META_ASSERT_TRUE(value == last + 1, "object type values must be consecutive numbers"); + if (last < value && value == EXTENSION_RANGE_START) + { + /* ok, but object type can't be used as array index any more */ + } + else + { + META_ASSERT_TRUE(value == last + 1, "object type values must be consecutive numbers"); + } last = value; } + + /* + * In long distance future this could be relaxed, but it will have impact + * on sonic and vendors. As currently object type is encoded on a single + * byte, and with this extensions change it will be encoded on 9 bits in + * sonic: + * - 8 bits for object type under SAI_OBJECT_TYPE_MAX) and extensions bit equal to 0 + * - 8 bits for extension object types reduced by 0x20000000 and extension bit seq to 1 + * This approach will allow to encode 255 object type for each range. + */ + META_ASSERT_TRUE(SAI_OBJECT_TYPE_MAX < 256, "object types must be able to encode on 1 byte"); + + i = SAI_OBJECT_TYPE_NULL; + + for (; i < SAI_OBJECT_TYPE_MAX; i++) + { + int value = sai_metadata_enum_sai_object_type_t.values[i]; + + META_ASSERT_TRUE(value == (int)i, "values from SAI_OBJECT_TYPE_NULL to SAI_OBJECT_TYPE_MAX must increase by 1"); + } } void check_attr_by_object_type() { META_LOG_ENTER(); - META_ASSERT_TRUE(SAI_OBJECT_TYPE_EXTENSIONS_MAX - SAI_OBJECT_TYPE_MAX < 50, "too many experimental object types"); + /* + * Extensions object types for now should be minimum, since it could be + * encoded on 1 byte in OID, but this could be later on relaxed. + */ + META_ASSERT_TRUE(EXTENSION_OBJECT_TYPE_COUNT < 64, "too many experimental object types"); - META_ASSERT_TRUE(SAI_OBJECT_TYPE_MAX <= SAI_OBJECT_TYPE_EXTENSIONS_MAX, "invalid object type count in metadata"); - META_ASSERT_TRUE(sai_metadata_attr_by_object_type_count == SAI_OBJECT_TYPE_EXTENSIONS_MAX, "invalid object type count in metadata"); + META_ASSERT_TRUE(sai_metadata_attr_by_object_type_count == (EXTENSION_OBJECT_TYPE_COUNT + SAI_OBJECT_TYPE_MAX), "invalid object type count in metadata"); - size_t i = 0; + size_t idx = 1; - for (; i < sai_metadata_attr_by_object_type_count; ++i) + for (; sai_metadata_all_object_type_infos[idx]; idx++) { - META_LOG_DEBUG("processing %zu, %s", i, sai_metadata_get_object_type_name((sai_object_type_t)i)); + META_LOG_DEBUG("processing %zu, %s", idx, sai_metadata_get_object_type_name(sai_metadata_all_object_type_infos[idx]->objecttype)); - META_ASSERT_NOT_NULL(sai_metadata_attr_by_object_type[i]); - - const sai_attr_metadata_t * const* const ot = sai_metadata_attr_by_object_type[i]; + const sai_attr_metadata_t * const* const ot = sai_metadata_all_object_type_infos[idx]->attrmetadata; size_t index = 0; @@ -388,7 +433,7 @@ void check_attr_by_object_type() { sai_object_type_t current = ot[index]->objecttype; - META_ASSERT_TRUE(current == i, "object type must be equal on object type list"); + META_ASSERT_TRUE(current == sai_metadata_all_object_type_infos[idx]->objecttype, "object type must be equal on object type list"); /* * For Switch Attribute we have crossed > 300 with Vendor extension @@ -397,17 +442,29 @@ void check_attr_by_object_type() META_ASSERT_TRUE(index < 300, "object defines > 300 attributes, metadata bug?"); META_ASSERT_TRUE(current > SAI_OBJECT_TYPE_NULL, "object type must be > NULL"); - META_ASSERT_TRUE(current < SAI_OBJECT_TYPE_EXTENSIONS_MAX, "object type must be < MAX"); + + if (current > SAI_OBJECT_TYPE_NULL && current < SAI_OBJECT_TYPE_MAX) + { + /* ok */ + } + else if (current >= (int)SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START && current < (int)SAI_OBJECT_TYPE_EXTENSIONS_RANGE_END) + { + /* ok */ + } + else + { + META_ASSERT_FAIL("invalid object type number: %d", current); + } /* META_LOG_DEBUG("processing indexer %lu", index); */ index++; } - META_LOG_DEBUG("attr index %zu for %s", index, sai_metadata_get_object_type_name((sai_object_type_t)i)); + META_LOG_DEBUG("attr index %zu for %s", index, sai_metadata_get_object_type_name(sai_metadata_all_object_type_infos[idx]->objecttype)); } - META_ASSERT_NULL(sai_metadata_attr_by_object_type[i]); + META_ASSERT_NULL(sai_metadata_all_object_type_infos[idx]); } bool is_valid_object_type( @@ -415,7 +472,15 @@ bool is_valid_object_type( { META_LOG_ENTER(); - return (ot > SAI_OBJECT_TYPE_NULL) && (ot < SAI_OBJECT_TYPE_EXTENSIONS_MAX); + /* possible later to add custom range, iterate over all OT */ + + if (ot > SAI_OBJECT_TYPE_NULL && ot < SAI_OBJECT_TYPE_MAX) + return true; + + if (ot >= (int)SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START && ot < (int)SAI_OBJECT_TYPE_EXTENSIONS_RANGE_END) + return true; + + return false; } void check_attr_object_type( @@ -817,7 +882,7 @@ void check_attr_allowed_object_types( META_MD_ASSERT_FAIL(md, "invalid allowed object type: %d", ot); } - const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[ot]; + const sai_object_type_info_t* info = sai_metadata_get_object_type_info(ot); META_ASSERT_NOT_NULL(info); @@ -2220,7 +2285,7 @@ void check_attr_reverse_graph( sai_object_type_t depobjecttype = md->allowedobjecttypes[index]; - const sai_object_type_info_t *oi = sai_metadata_all_object_type_infos[depobjecttype]; + const sai_object_type_info_t *oi = sai_metadata_get_object_type_info(depobjecttype); META_ASSERT_NOT_NULL(oi->revgraphmembers); @@ -2281,8 +2346,8 @@ void check_attr_reverse_graph( rm->attrmetadata->attrid == md->attrid) { META_LOG_DEBUG("dep %s ot %s attr %s\n", - sai_metadata_enum_sai_object_type_t.valuesnames[depobjecttype], - sai_metadata_enum_sai_object_type_t.valuesnames[md->objecttype], + sai_metadata_get_object_type_name(depobjecttype), + sai_metadata_get_object_type_name(md->objecttype), md->attridname); defined = true; @@ -2461,7 +2526,7 @@ void check_attr_existing_objects( * not be NULL after creation. */ - if (sai_metadata_all_object_type_infos[md->objecttype]->isnonobjectid) + if (sai_metadata_get_object_type_info(md->objecttype)->isnonobjectid) { if (md->storedefaultvalue) { @@ -3231,8 +3296,7 @@ void check_attr_default_attrvalue( return; } - const sai_object_type_info_t* info = - sai_metadata_all_object_type_infos[md->objecttype]; + const sai_object_type_info_t* info = sai_metadata_get_object_type_info(md->objecttype); /* search for attribute */ @@ -3272,12 +3336,12 @@ void check_attr_default_attrvalue( if (count == 0) { META_MD_ASSERT_FAIL(md, "oid attribute with %s is not present in %s", - sai_metadata_all_object_type_infos[md->defaultvalueobjecttype]->objecttypename, - sai_metadata_all_object_type_infos[md->objecttype]->objecttypename); + sai_metadata_get_object_type_info(md->defaultvalueobjecttype)->objecttypename, + sai_metadata_get_object_type_info(md->objecttype)->objecttypename); } META_MD_ASSERT_FAIL(md, "too many attributes with %s for default value attrvalue", - sai_metadata_all_object_type_infos[md->defaultvalueobjecttype]->objecttypename); + sai_metadata_get_object_type_info(md->defaultvalueobjecttype)->objecttypename); } void check_attr_fdb_flush( @@ -3379,7 +3443,7 @@ void check_attr_extension_flag( const sai_object_type_info_t* oi = sai_metadata_get_object_type_info(md->objecttype); - if (md->attrid >= oi->attridend && md->attrid < CUSTOM_ATTR_RANGE_START) + if (md->attrid >= oi->attridend && md->attrid >= EXTENSION_RANGE_START) { META_ASSERT_TRUE(md->isextensionattr, "attribute %s expected to be extension", md->attridname); } @@ -3478,53 +3542,40 @@ void check_stat_enums() * statistics (like PORT, etc) have stat enum values populated. */ - size_t i = SAI_OBJECT_TYPE_NULL; + size_t i = 1; int count = 0; - for (; i <= SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++i) + for (; sai_metadata_all_object_type_infos[i] != NULL; ++i) { const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[i]; - if (info == NULL) - { - continue; - } - if (info->statenum != NULL) { count++; } } - META_ASSERT_TRUE(count > 10, "at least some sai_object_type_into_t->statenum must be populated"); + META_ASSERT_TRUE(count > 20, "at least some sai_object_type_into_t->statenum must be populated"); } void check_object_infos() { META_LOG_ENTER(); - size_t i = SAI_OBJECT_TYPE_NULL; + size_t i = 1; - for (; i <= SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++i) + META_ASSERT_NULL(sai_metadata_all_object_type_infos[0]); + + for (; sai_metadata_all_object_type_infos[i] != NULL; ++i) { const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[i]; - if (i == SAI_OBJECT_TYPE_NULL || i == SAI_OBJECT_TYPE_EXTENSIONS_MAX) - { - META_ASSERT_NULL(info); - continue; - } - META_ASSERT_NOT_NULL(info->enummetadata); - META_ASSERT_TRUE(info->enummetadata->objecttype == i, "should be equal"); - - META_ASSERT_TRUE(info->objecttype == i, "object type mismatch"); - META_ASSERT_NOT_NULL(info->objecttypename); - META_LOG_DEBUG("processing object type: %s", sai_metadata_get_object_type_name((sai_object_type_t)i)); + META_LOG_DEBUG("processing object type: %s", sai_metadata_get_object_type_name(info->objecttype)); META_ASSERT_TRUE(info->attridstart == 0, "attribute enum start should be zero"); META_ASSERT_TRUE(info->attridend > 0, "attribute enum end must be > 0"); @@ -3562,6 +3613,10 @@ void check_object_infos() has_custom_range_attrs = true; } + else if (am->attrid == EXTENSION_RANGE_START) + { + has_extensions_attrs = true; + } else { if (is_flag_enum(info->enummetadata)) @@ -3626,33 +3681,31 @@ void check_object_infos() else { META_ENUM_ASSERT_FAIL(info->enummetadata, "end of attributes don't match attr count on %s", - sai_metadata_get_object_type_name((sai_object_type_t)i)); + sai_metadata_get_object_type_name(info->objecttype)); } } } + + /* guard */ + META_ASSERT_NULL(sai_metadata_all_object_type_infos[i]); } void check_non_object_id_object_types() { META_LOG_ENTER(); - size_t i = SAI_OBJECT_TYPE_NULL; + size_t idx = 1; - for (; i <= SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++i) + for (; sai_metadata_all_object_type_infos[idx]; ++idx) { - const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[i]; - - if (info == NULL) - { - continue; - } + const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[idx]; if (!info->isnonobjectid) { if (info->structmemberscount != 0 || info->structmembers != NULL) { - META_ASSERT_FAIL("object type %zu is non object id but struct members defined", i); + META_ASSERT_FAIL("object type %u is non object id but struct members defined", info->objecttype); } continue; @@ -3768,7 +3821,7 @@ void check_non_object_id_object_types() /* non object id struct can't contain object id which is also non object id */ - const sai_object_type_info_t* sinfo = sai_metadata_all_object_type_infos[ot]; + const sai_object_type_info_t* sinfo = sai_metadata_get_object_type_info(ot); META_ASSERT_NOT_NULL(sinfo); @@ -3804,13 +3857,13 @@ void check_non_object_id_object_attrs() { META_LOG_ENTER(); - size_t i = SAI_OBJECT_TYPE_NULL; + size_t i = 1; - for (; i <= SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++i) + for (; sai_metadata_all_object_type_infos[i] != NULL; ++i) { const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[i]; - if (info == NULL || !info->isnonobjectid) + if (!info->isnonobjectid) { continue; } @@ -3917,6 +3970,43 @@ void check_attr_sorted_by_id_name() META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name_ext("ZZZ")); /* after all attr names */ } +uint32_t ot2idx( + _In_ sai_object_type_t ot) +{ + /* + * This function will convert extension object type to object type number + * that will be defined after SAI_OBJECT_TYPE_MAX. This will be used to + * index in array + */ + + if (ot >= SAI_OBJECT_TYPE_NULL && ot < SAI_OBJECT_TYPE_MAX) + return ot; + + if (ot >= (int)SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START && ot < (int)SAI_OBJECT_TYPE_EXTENSIONS_RANGE_END) + return SAI_OBJECT_TYPE_MAX + (ot - SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START); + + META_ASSERT_FAIL("invalid object type specified %d", ot); +} + +sai_object_type_t idx2ot( + _In_ uint32_t idx) +{ + if (idx < SAI_OBJECT_TYPE_MAX) + return (sai_object_type_t)idx; + + uint32_t i = 1; + + for (; sai_metadata_all_object_type_infos[i]; i++) + { + if (i == idx) + { + return sai_metadata_all_object_type_infos[i]->objecttype; + } + } + + META_ASSERT_FAIL("invalid index: %d", idx); +} + void list_loop( _In_ const sai_object_type_info_t* info, _In_ const sai_object_type_t *visited, @@ -3927,20 +4017,20 @@ void list_loop( META_LOG_ENTER(); META_LOG_WARN("LOOP DETECTED on object type: %s", - sai_metadata_enum_sai_object_type_t.valuesnames[info->objecttype]); + sai_metadata_get_object_type_name(info->objecttype)); for (; levelidx < level; ++levelidx) { sai_object_type_t ot = visited[levelidx]; - const char* ot_name = sai_metadata_enum_sai_object_type_t.valuesnames[ot]; + const char* ot_name = sai_metadata_get_object_type_name(ot); const sai_attr_metadata_t* m = sai_metadata_get_attr_metadata(ot, attributes[levelidx]); META_LOG_WARN(" %s: %s", ot_name, m->attridname); } - META_LOG_WARN(" -> %s", sai_metadata_enum_sai_object_type_t.valuesnames[info->objecttype]); + META_LOG_WARN(" -> %s", sai_metadata_get_object_type_name(info->objecttype)); if (level >= 0) { @@ -4027,7 +4117,7 @@ void check_objects_for_loops_recursive( for (; j < m->allowedobjecttypeslength; ++j) { - const sai_object_type_info_t* next = sai_metadata_all_object_type_infos[ m->allowedobjecttypes[j] ]; + const sai_object_type_info_t* next = sai_metadata_get_object_type_info(m->allowedobjecttypes[j]); check_objects_for_loops_recursive(next, visited, attributes, level + 1); } @@ -4052,7 +4142,7 @@ void check_objects_for_loops_recursive( for (; k < m->allowedobjecttypeslength; k++) { - const sai_object_type_info_t* next = sai_metadata_all_object_type_infos[ m->allowedobjecttypes[k] ]; + const sai_object_type_info_t* next = sai_metadata_get_object_type_info(m->allowedobjecttypes[k]); check_objects_for_loops_recursive(next, visited, attributes, level + 1); } @@ -4069,22 +4159,17 @@ void check_objects_for_loops() { META_LOG_ENTER(); - sai_object_type_t visited_objects[SAI_OBJECT_TYPE_EXTENSIONS_MAX]; - uint32_t visited_attributes[SAI_OBJECT_TYPE_EXTENSIONS_MAX]; + sai_object_type_t visited_objects[TOTAL_OBJECT_TYPE_COUNT]; + uint32_t visited_attributes[TOTAL_OBJECT_TYPE_COUNT]; - size_t i = SAI_OBJECT_TYPE_NULL; + size_t i = 1; - for (; i <= SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++i) + for (; sai_metadata_all_object_type_infos[i] != NULL; ++i) { const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[i]; - if (info == NULL) - { - continue; - } - - memset(visited_objects, 0, SAI_OBJECT_TYPE_EXTENSIONS_MAX * sizeof(sai_object_type_t)); - memset(visited_attributes, 0, SAI_OBJECT_TYPE_EXTENSIONS_MAX * sizeof(uint32_t)); + memset(visited_objects, 0, TOTAL_OBJECT_TYPE_COUNT * sizeof(sai_object_type_t)); + memset(visited_attributes, 0, TOTAL_OBJECT_TYPE_COUNT * sizeof(uint32_t)); check_objects_for_loops_recursive(info, visited_objects, visited_attributes, 0); } @@ -4120,17 +4205,12 @@ void check_read_only_attributes() * object type defines at least 1 attribute. */ - size_t i = SAI_OBJECT_TYPE_NULL; + size_t i = 1; - for (; i <= SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++i) + for (; sai_metadata_all_object_type_infos[i] != NULL; ++i) { const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[i]; - if (info == NULL) - { - continue; - } - size_t index = 0; /* check all listed attributes under this object type */ @@ -4152,7 +4232,7 @@ void check_read_only_attributes() if (index < 1) { META_ASSERT_FAIL("object %s must define at least 1 attribute", - sai_metadata_get_object_type_name((sai_object_type_t)i)); + sai_metadata_get_object_type_name(info->objecttype)); } if (non_read_only_count == 0) @@ -4164,7 +4244,7 @@ void check_read_only_attributes() */ META_LOG_WARN("object %s has only READ_ONLY attributes", - sai_metadata_enum_sai_object_type_t.valuesnames[i]); + sai_metadata_get_object_type_name(info->objecttype)); } } } @@ -4286,7 +4366,7 @@ void check_single_non_object_id_for_rev_graph( * member. */ - const sai_object_type_info_t *oi = sai_metadata_all_object_type_infos[depobjecttype]; + const sai_object_type_info_t *oi = sai_metadata_get_object_type_info(depobjecttype); META_ASSERT_NOT_NULL(oi->revgraphmembers); @@ -4347,8 +4427,8 @@ void check_single_non_object_id_for_rev_graph( if (rm->structmember->allowedobjecttypes[i] == depobjecttype) { META_LOG_DEBUG("dep %s ot %s attr %s\n", - sai_metadata_enum_sai_object_type_t.valuesnames[depobjecttype], - sai_metadata_enum_sai_object_type_t.valuesnames[objecttype], + sai_metadata_get_object_type_name(depobjecttype), + sai_metadata_get_object_type_name(objecttype), sm->membername); defined = true; @@ -4392,12 +4472,10 @@ void check_reverse_graph_for_non_object_id() * values are checked during standard loop of attribute above. */ - size_t i = SAI_OBJECT_TYPE_NULL; + size_t i = 1; - for (; i <= SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++i) + for (; sai_metadata_all_object_type_infos[i] != NULL; ++i) { - sai_object_type_t objecttype = (sai_object_type_t)i; - const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[i]; if (info == NULL || !info->isnonobjectid) @@ -4438,7 +4516,7 @@ void check_reverse_graph_for_non_object_id() sai_object_type_t depobjecttype = m->allowedobjecttypes[k]; - check_single_non_object_id_for_rev_graph(m, objecttype, depobjecttype); + check_single_non_object_id_for_rev_graph(m, info->objecttype, depobjecttype); } } } @@ -5029,16 +5107,6 @@ void check_single_object_info( check_attr_end(oi); } -void check_api_max() -{ - META_LOG_ENTER(); - - META_ASSERT_TRUE(SAI_API_MAX <= SAI_API_EXTENSIONS_MAX, "expected api MAX to be less equal than extensions MAX"); - - META_ASSERT_TRUE(sai_metadata_enum_sai_api_t.valuescount == SAI_API_EXTENSIONS_MAX, - "SAI_API_EXTENSIONS_MAX should be equal to number of SAI_API*"); -} - void check_backward_comparibility_defines() { META_LOG_ENTER(); @@ -5060,14 +5128,14 @@ void helper_check_graph_connected( { META_LOG_ENTER(); - if (visited[ot] == ot) + if (visited[ot2idx(ot)] == ot) { return; } - visited[ot] = ot; + visited[ot2idx(ot)] = ot; - const sai_object_type_info_t *oi = sai_metadata_all_object_type_infos[ot]; + const sai_object_type_info_t *oi = sai_metadata_get_object_type_info(ot); size_t i = 0; @@ -5123,17 +5191,17 @@ void check_graph_connected() * Check if all objects are used and are not "disconnected" from the graph. */ - sai_object_type_t visited[SAI_OBJECT_TYPE_EXTENSIONS_MAX]; + sai_object_type_t visited[TOTAL_OBJECT_TYPE_COUNT]; - memset(visited, 0, SAI_OBJECT_TYPE_EXTENSIONS_MAX * sizeof(sai_object_type_t)); + memset(visited, 0, TOTAL_OBJECT_TYPE_COUNT * sizeof(sai_object_type_t)); helper_check_graph_connected(SAI_OBJECT_TYPE_PORT, visited); - size_t i = 0; + uint32_t i = 1; - for (; i < SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++i) + for (; sai_metadata_all_object_type_infos[i] != NULL; ++i) { - if (visited[i] == (sai_object_type_t)i) + if (visited[i] == sai_metadata_all_object_type_infos[i]->objecttype) { continue; } @@ -5148,7 +5216,7 @@ void check_graph_connected() continue; } - if (SAI_OBJECT_TYPE_DEBUG_COUNTER == i) + if (SAI_OBJECT_TYPE_DEBUG_COUNTER == idx2ot(i)) { /* * Allow debug counters to be disconnected from main graph @@ -5172,18 +5240,18 @@ void check_get_attr_metadata() int count = 0; - size_t ot = 0; + size_t i = 1; - for (; ot < SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++ot) + for (; sai_metadata_all_object_type_infos[i]; ++i) { - const sai_attr_metadata_t* const* mda = sai_metadata_attr_by_object_type[ot]; + const sai_attr_metadata_t* const* mda = sai_metadata_all_object_type_infos[i]->attrmetadata; int idx = 0; while (mda[idx]) { const sai_attr_metadata_t* m = mda[idx++]; - const sai_attr_metadata_t* md = sai_metadata_get_attr_metadata(ot, m->attrid); + const sai_attr_metadata_t* md = sai_metadata_get_attr_metadata(sai_metadata_all_object_type_infos[i]->objecttype, m->attrid); META_ASSERT_NOT_NULL(md); META_ASSERT_TRUE(m == md, "different attribute found, fatal"); @@ -5211,16 +5279,13 @@ void check_get_attr_metadata_custom_range() size_t count = 0; - size_t ot = 0; + int i = 1; - for (; ot < SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++ot) + for (; sai_metadata_all_object_type_infos[i]; i++) { - const sai_object_type_info_t* oti = sai_metadata_get_object_type_info(ot); - - if (oti == NULL) - continue; + const sai_object_type_info_t* oti = sai_metadata_all_object_type_infos[i]; - const sai_attr_metadata_t* const* mda = sai_metadata_attr_by_object_type[ot]; + const sai_attr_metadata_t* const* mda = sai_metadata_all_object_type_infos[i]->attrmetadata; if (oti->enummetadata->containsflags) { @@ -5230,7 +5295,7 @@ void check_get_attr_metadata_custom_range() { const sai_attr_metadata_t* m = mda[idx++]; - const sai_attr_metadata_t* md = sai_metadata_get_attr_metadata(ot, m->attrid); + const sai_attr_metadata_t* md = sai_metadata_get_attr_metadata(sai_metadata_all_object_type_infos[i]->objecttype, m->attrid); META_ASSERT_NOT_NULL(md); META_ASSERT_TRUE(m == md, "different attribute found, fatal"); @@ -5250,7 +5315,7 @@ void check_get_attr_metadata_custom_range() while (mda[idx]) { const sai_attr_metadata_t* m = mda[idx]; - const sai_attr_metadata_t* md = sai_metadata_get_attr_metadata(ot, m->attrid); + const sai_attr_metadata_t* md = sai_metadata_get_attr_metadata(sai_metadata_all_object_type_infos[i]->objecttype, m->attrid); META_ASSERT_NOT_NULL(md); META_ASSERT_TRUE(m == md, "different attribute found, fatal"); @@ -5285,7 +5350,32 @@ void check_attr_get_outside_range() int ot = -10; - for (; ot < (int)(SAI_OBJECT_TYPE_EXTENSIONS_MAX + 10); ++ot) + for (; ot < (int)(SAI_OBJECT_TYPE_MAX + 10); ++ot) + { + const sai_object_type_info_t* oti = sai_metadata_get_object_type_info(ot); + + if (oti == NULL) + continue; + + int idx = -10; + + for (; idx < (int)(oti->attrmetadatalength + 10); idx++) + { + const sai_attr_metadata_t* md = sai_metadata_get_attr_metadata(ot, (sai_attr_id_t)idx); + + if (md == NULL) + continue; + + if ((int)md->attrid != idx) + { + META_MD_ASSERT_FAIL(md, "attr %u expected to be %u", md->attrid, idx); + } + } + } + + ot = SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START -10 ; + + for (; ot < (int)(SAI_OBJECT_TYPE_EXTENSIONS_RANGE_END + 10); ++ot) { const sai_object_type_info_t* oti = sai_metadata_get_object_type_info(ot); @@ -5315,22 +5405,22 @@ void check_custom_range_attributes() /* Checks whether attribute is correctly marked as custom */ - size_t ot = 0; + size_t i = 1; - for (; ot < SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++ot) + for (; sai_metadata_all_object_type_infos[i]; i++) { - const sai_attr_metadata_t* const* mda = sai_metadata_attr_by_object_type[ot]; + const sai_attr_metadata_t* const* mda = sai_metadata_all_object_type_infos[i]->attrmetadata; int idx = 0; while (mda[idx]) { const sai_attr_metadata_t* m = mda[idx++]; - const sai_attr_metadata_t* md = sai_metadata_get_attr_metadata(ot, m->attrid); + const sai_attr_metadata_t* md = sai_metadata_get_attr_metadata(sai_metadata_all_object_type_infos[i]->objecttype, m->attrid); META_ASSERT_NOT_NULL(md); - if (md->attrid >= CUSTOM_ATTR_RANGE_START) + if (md->attrid >= CUSTOM_ATTR_RANGE_START && md->attrid < (EXTENSION_RANGE_START)) { META_ASSERT_TRUE(md->iscustom, "expected to be marked as custom attribute, %s", md->attridname); } @@ -5412,11 +5502,11 @@ void check_object_type_attributes() { META_LOG_ENTER(); - size_t i = 0; + size_t i = 1; - for (; i < sai_metadata_attr_by_object_type_count; ++i) + for (; sai_metadata_all_object_type_infos[i]; i++) { - check_single_object_type_attributes(sai_metadata_attr_by_object_type[i]); + check_single_object_type_attributes(sai_metadata_all_object_type_infos[i]->attrmetadata); } } @@ -5424,14 +5514,12 @@ void check_all_object_infos() { META_LOG_ENTER(); - size_t i = SAI_OBJECT_TYPE_NULL + 1; + size_t i = 1; - for (; i < SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++i) + for (; sai_metadata_all_object_type_infos[i] != NULL; ++i) { check_single_object_info(sai_metadata_all_object_type_infos[i]); } - - META_ASSERT_TRUE((size_t)SAI_OBJECT_TYPE_EXTENSIONS_MAX == (size_t)SAI_OBJECT_TYPE_EXTENSIONS_RANGE_END, "must be equal"); } void check_ignored_attributes() @@ -5526,7 +5614,14 @@ void check_enum_flags_type_ranges( /* this check can be relaxed, we allow now 16 types of ranges */ - META_ASSERT_TRUE((val < (16*RANGE_BASE)), "range value 0x%x is too high on %s", val, name); + if (val < EXTENSION_RANGE_START) + { + META_ASSERT_TRUE((val < (16*RANGE_BASE)), "range value 0x%x is too high on %s", val, name); + } + else + { + META_ASSERT_TRUE((val < (16*RANGE_BASE + EXTENSION_RANGE_START)), "range value 0x%x is too high on %s", val, name); + } if ((val != prev + 1) && (val & 0xFFF) && ((val & ~0xFFF) == (prev & ~0xFFF))) { @@ -5622,6 +5717,14 @@ void check_enum_flags_type_none( * not flags, attribute value can't be used as array index. */ } + else if (value == EXTENSION_RANGE_START) + { + /* + * Object contains extensions attributes, they still needs + * to be increasing by 1 but since those are not flags, + * attribute value can't be used as array index. + */ + } else { META_ENUM_ASSERT_FAIL(emd, "values are not increasing by 1: last: %d current: %d, should be marked as @flags?", last, value); @@ -5724,6 +5827,8 @@ void check_max_conditions_len() META_ASSERT_TRUE(SAI_METADATA_MAX_CONDITIONS_LEN > 0, "must be positive"); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" void check_object_type_extension_max_value() { META_LOG_ENTER(); @@ -5732,12 +5837,27 @@ void check_object_type_extension_max_value() * It can be handy for vendors to encode object type value on single byte * in every object it for easy object identification. We assume that we * will have no more than 255 objects types on SAI right now. + * + * But since we are moving object type extensions to higher range to be + * backward compatible to not shift enums, vendor still may want to encode + * that in 1 byte, for example 127 id's for regular object types and 127 + * for extended, or 191 for base, and 63 for extended. + * + * At the time this comment is made, we have 110 base and 20 extended. + * Allowing extra 32 on each range we can fit in 191 and 63 on 1 byte. + * */ - META_ASSERT_TRUE(SAI_OBJECT_TYPE_EXTENSIONS_MAX < 256, "max object type can be 255 to be encoded on single byte"); + META_LOG_INFO("SAI_OBJECT_TYPE_MAX = %d, EXTENSION_OBJECT_TYPE_COUNT = %d", SAI_OBJECT_TYPE_MAX, EXTENSION_OBJECT_TYPE_COUNT); - META_ASSERT_TRUE(SAI_OBJECT_TYPE_MAX < SAI_OBJECT_TYPE_EXTENSIONS_MAX, "max object must be less than max extensions"); + /* + * This check may be removed, but it will need to be brought into attention on SAI meeting. + */ + META_ASSERT_TRUE(SAI_OBJECT_TYPE_MAX < 192 && EXTENSION_OBJECT_TYPE_COUNT < 64, "exceeding this range will not allow to encode object types to single byte"); + + META_ASSERT_TRUE(TOTAL_OBJECT_TYPE_COUNT < 256, "TOTAL_OBJECT_TYPE_COUNT bust be < 256 if it should be possible to encode object type on single byte"); } +#pragma GCC diagnostic pop void check_global_apis() { @@ -5902,6 +6022,41 @@ void check_json_type_size() META_ASSERT_TRUE(sizeof(sai_s8_list_t) == sizeof(sai_json_t), "json type is expected to have same size as s8 list"); } +void check_api_extensions() +{ + SAI_META_LOG_ENTER(); + + /* + * Check if defined extensions api can be fit into 1 byte. + * This check can be relaxed in the future. + */ + + if (SAI_API_EXTENSIONS_RANGE_END - SAI_API_EXTENSIONS_RANGE_START > 255) + { + META_ASSERT_FAIL("api extensions %d > 255", (SAI_API_EXTENSIONS_RANGE_END - SAI_API_EXTENSIONS_RANGE_START)); + } + + sai_api_t api = (sai_api_t)SAI_API_EXTENSIONS_RANGE_START; + + META_ASSERT_TRUE(api == 0x20000000, "api should be correctly assigned"); +} + +void check_object_type_index() +{ + META_LOG_ENTER(); + + META_ASSERT_TRUE(ot2idx(0) == 0, "must be zero"); + META_ASSERT_TRUE(idx2ot(0) == 0, "must be zero"); + + uint32_t i = 1; + + for (; sai_metadata_all_object_type_infos[i]; i++) + { + META_ASSERT_TRUE(ot2idx(sai_metadata_all_object_type_infos[i]->objecttype) == i, "invalid ot2idx"); + META_ASSERT_TRUE(idx2ot(i) == sai_metadata_all_object_type_infos[i]->objecttype, "invalid idx2ot"); + } +} + int main(int argc, char **argv) { debug = (argc > 1); @@ -5912,6 +6067,7 @@ int main(int argc, char **argv) check_all_enums_values(); check_enums_ignore_values(); check_sai_status(); + check_object_type_index(); check_object_type(); check_attr_by_object_type(); check_object_type_attributes(); @@ -5930,7 +6086,6 @@ int main(int argc, char **argv) check_reverse_graph_for_non_object_id(); check_acl_table_fields_and_acl_entry_fields(); check_acl_entry_actions(); - check_api_max(); check_backward_comparibility_defines(); check_graph_connected(); check_get_attr_metadata(); @@ -5952,6 +6107,7 @@ int main(int argc, char **argv) check_json_type_size(); check_custom_range_attributes(); check_attr_get_outside_range(); + check_api_extensions(); SAI_META_LOG_DEBUG("log test"); diff --git a/meta/saiserializetest.c b/meta/saiserializetest.c index 0fddbc65d..6987a25a6 100644 --- a/meta/saiserializetest.c +++ b/meta/saiserializetest.c @@ -1683,7 +1683,7 @@ void test_serialize_attribute() sai_attribute_t attribute = {0}; const sai_attr_metadata_t* amd; - amd = sai_metadata_attr_by_object_type[SAI_OBJECT_TYPE_SWITCH][0]; + amd = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, 0); attribute.id = SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS; attribute.value.u32 = 3; diff --git a/meta/test.pm b/meta/test.pm index c3f051b04..c3b7a1820 100644 --- a/meta/test.pm +++ b/meta/test.pm @@ -151,9 +151,6 @@ sub CreateCustomRangeTest sub CreateCustomRangeAll { - WriteTest "#pragma GCC diagnostic push"; - WriteTest "#pragma GCC diagnostic ignored \"-Wsuggest-attribute=noreturn\""; - DefineTestName "custom_range_all_test"; # purpose of this test is to make sure @@ -176,13 +173,11 @@ sub CreateCustomRangeAll next if $enum eq "SAI_OBJECT_TYPE_CUSTOM_RANGE_END"; WriteTest " TEST_ASSERT_TRUE($enum == 0x10000000, \"invalid custom range start for $enum\");" if $enum =~ /_START$/; - WriteTest " TEST_ASSERT_TRUE($enum > 0x10000000, \"invalid custom range end for $enum\");" if $enum =~ /_END$/; + WriteTest " TEST_ASSERT_TRUE($enum < 0x20000000, \"invalid custom range end for $enum\");" if $enum =~ /_END$/; } } WriteTest "}"; - - WriteTest "#pragma GCC diagnostic pop"; } sub CreateEnumSizeCheckTest @@ -254,8 +249,7 @@ sub CreateApiNameTest my @objects = @{ $main::SAI_ENUMS{sai_object_type_t}{values} }; - WriteTest " sai_object_type_t checked[SAI_OBJECT_TYPE_EXTENSIONS_MAX];"; - WriteTest " memset(checked, 0, SAI_OBJECT_TYPE_EXTENSIONS_MAX * sizeof(sai_object_type_t));"; + WriteTest " int visited = 1; /* 1 for NULL object */"; WriteTest " void *dummy = NULL;"; @@ -268,7 +262,7 @@ sub CreateApiNameTest if (IsSpecialObject($ot)) { # those objects are special, just attributes, no APIs - WriteTest " checked[(int)$ot] = $ot;"; + WriteTest " visited++;"; next; } @@ -327,7 +321,7 @@ sub CreateApiNameTest WriteTest " dummy = &se;"; WriteTest " dummy = ≥"; WriteTest " dummy = NULL;"; - WriteTest " checked[(int)$ot] = $ot;"; + WriteTest " visited++;"; } else { @@ -360,21 +354,14 @@ sub CreateApiNameTest WriteTest " dummy = &se;"; WriteTest " dummy = ≥"; WriteTest " dummy = NULL;"; - WriteTest " checked[(int)$ot] = $ot;"; + WriteTest " visited++;"; } WriteTest " }"; } - WriteTest " int index = SAI_OBJECT_TYPE_NULL;"; - - WriteTest " for (; index < (int)SAI_OBJECT_TYPE_EXTENSIONS_MAX; ++index)"; - WriteTest " {"; - WriteTest " printf(\"checking: %s checked (%d) == index (%d)\\n\","; - WriteTest " sai_metadata_enum_sai_object_type_t.valuesnames[index],"; - WriteTest " checked[index],(sai_object_type_t)index);"; - WriteTest " TEST_ASSERT_TRUE(checked[index] == (sai_object_type_t)index, \"not all objects were processed\");"; - WriteTest " }"; + WriteTest " int sum = SAI_OBJECT_TYPE_MAX + (SAI_OBJECT_TYPE_EXTENSIONS_RANGE_END - SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START);"; + WriteTest " TEST_ASSERT_TRUE_EXT(sum == visited, \"not all objects were processed, expexted: %d, but got: %d\", sum, visited);"; WriteTest " PP(dummy);"; @@ -599,9 +586,6 @@ sub CreateStructUnionSizeCheckTest my %STRUCTS = (); - WriteTest "#pragma GCC diagnostic push"; - WriteTest "#pragma GCC diagnostic ignored \"-Wsuggest-attribute=noreturn\""; - DefineTestName "struct_union_size"; WriteTest "{"; @@ -635,7 +619,6 @@ sub CreateStructUnionSizeCheckTest } WriteTest "}"; - WriteTest "#pragma GCC diagnostic pop"; } sub WriteTestHeader @@ -691,6 +674,7 @@ sub CreatePragmaPush WriteTest "#pragma GCC diagnostic push"; WriteTest "#pragma GCC diagnostic ignored \"-Wpragmas\""; WriteTest "#pragma GCC diagnostic ignored \"-Wenum-conversion\""; + WriteTest "#pragma GCC diagnostic ignored \"-Wsuggest-attribute=noreturn\""; } sub CreatePragmaPop @@ -698,6 +682,32 @@ sub CreatePragmaPop WriteTest "#pragma GCC diagnostic pop"; } +sub CreateExtensionRangeTest +{ + DefineTestName "extension_range_test"; + + # purpose of this test is to make sure + # all extensions range bases are from + + WriteTest "{"; + + for my $key (sort keys %main::SAI_ENUMS) + { + next if not defined $main::SAI_ENUMS{$key}{ranges}; + + my @ranges = @{ $main::SAI_ENUMS{$key}{ranges} }; + + for my $range (@ranges) + { + next if not $range =~ /EXTENSIONS_RANGE_BASE/; + + WriteTest " TEST_ASSERT_TRUE($range == 0x20000000, \"invalid extension range base for $range\");"; + } + } + + WriteTest "}"; +} + sub CreateTests { WriteTestHeader(); @@ -732,10 +742,12 @@ sub CreateTests CreateStructUnionSizeCheckTest(); - CreatePragmaPop(); - CreateCustomRangeAll(); + CreateExtensionRangeTest(); + + CreatePragmaPop(); + WriteTestMain(); }