diff --git a/.gitignore b/.gitignore index 725c02f8e..77c2eb6fe 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ meta/sai.thrift meta/sai_adapter.py meta/sai_rpc_server.cpp meta/sai_rpc_frontend +meta/saiattrversion.h # temporary files **/*~ diff --git a/meta/Makefile b/meta/Makefile index 870752cf4..91014dfcf 100644 --- a/meta/Makefile +++ b/meta/Makefile @@ -121,10 +121,13 @@ xml: $(DEPS) Doxyfile Doxyfile.compat $(CONSTHEADERS) EXTRA = acronyms.txt aspell.en.pws *.pm *.cap +saiattrversion.h: $(DEPS) attrversion.sh + ./attrversion.sh + saimetadatasize.h: $(DEPS) ./size.sh -saimetadatatest.c saimetadata.c saimetadata.h: xml $(XMLDEPS) parse.pl $(CONSTHEADERS) $(EXTRA) +saimetadatatest.c saimetadata.c saimetadata.h: xml $(XMLDEPS) parse.pl $(CONSTHEADERS) $(EXTRA) saiattrversion.h perl -I. parse.pl RPC_MODULES=$(shell find rpc -type f -name "*.pm") @@ -190,7 +193,7 @@ sai_rpc_frontend: rpc sai_rpc_frontend.cpp sai_rpc_frontend.main.cpp sai_rpc_ser clean: rm -f *.o *~ .*~ *.tmp .*.swp .*.swo *.bak sai*.gv sai*.svg *.o.symbols doxygen*.db *.so - rm -f saimetadata.h saimetadatasize.h saimetadata.c saimetadatatest.c saiswig.i + rm -f saimetadata.h saimetadatasize.h saimetadata.c saimetadatatest.c saiswig.i saiattrversion.h rm -f saisanitycheck saimetadatatest saiserializetest saidepgraphgen sai_rpc_frontend rm -f sai.thrift sai_rpc_server.cpp sai_adapter.py rm -f *.gcda *.gcno *.gcov diff --git a/meta/aspell.en.pws b/meta/aspell.en.pws index 370bafccb..19a2b6d84 100644 --- a/meta/aspell.en.pws +++ b/meta/aspell.en.pws @@ -128,6 +128,7 @@ netdevs netlink nexthop nexthopgroup +nextrelease NPUs objlist offsetof diff --git a/meta/attrversion.sh b/meta/attrversion.sh new file mode 100755 index 000000000..205744ab5 --- /dev/null +++ b/meta/attrversion.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# +# Copyright (c) 2021 Microsoft Open Technologies, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# +# Microsoft would like to thank the following companies for their review and +# assistance with these files: Intel Corporation, Mellanox Technologies Ltd, +# Dell Products, L.P., Facebook, Inc., Marvell International Ltd. +# +# @file attrversion.sh +# +# @brief This module defines attr version script +# + +OUTPUT="saiattrversion.h" + +if ! git rev-parse --git-dir > /dev/null 2>&1; then + +echo "WARNING: this is not git repository, will skip generating saiattrversion.h" +cat /dev/null > $OUTPUT +exit +fi + +# since api sai_query_api_version was introduced at v1.10.0 and we are enum +# backward compatible from v1.9.0 then it make sense to list all attributes +# version at v1.10.0, since it's min version to query vendor for api version + +BASE="v1.10.0" + +set -e + +TAGS=$(git tag --sort=v:refname | grep -P "^v\d+\.\d+.\d+$" | sed -n -e '/'$BASE'/,$p'; echo HEAD) + +(for tag in $TAGS; do git grep -P "^\s+SAI_\w+_ATTR_" $tag ../inc ../experimental | cat; done; + grep -P "^\s+SAI_\w+_ATTR_" ../inc/sai*h ../experimental/sai*h | perl -npe '$_.="HEAD:"' ) | \ + perl -ne '/^(\S+):..\/(\S+)\/\S+.h:\s+(SAI_\w+_ATTR_\w+)/; print "#define $3 \"$1\" /* $2 */\n" if not defined $h{$3};$h{$3}=1' > $OUTPUT diff --git a/meta/parse.pl b/meta/parse.pl index aeab5f67b..0c7677c2e 100755 --- a/meta/parse.pl +++ b/meta/parse.pl @@ -69,6 +69,7 @@ our %GLOBAL_APIS = (); our %OBJECT_TYPE_BULK_MAP = (); our %SAI_ENUMS_CUSTOM_RANGES = (); +our %ATTR_API_VER = (); my $FLAGS = "MANDATORY_ON_CREATE|CREATE_ONLY|CREATE_AND_SET|READ_ONLY|KEY"; my $ENUM_FLAGS_TYPES = "(none|strict|mixed|ranges|free)"; @@ -2294,6 +2295,46 @@ sub ProcessIsExtensionAttr return "false"; } +sub ProcessApiVersion +{ + my ($attr, $type) = @_; + + # for those attributes use the same version as MIN, since those + # attributes are auto generated + + $attr = "SAI_ACL_ENTRY_ATTR_USER_DEFINED_FIELD_GROUP_MIN" + if ($attr =~ /^SAI_ACL_ENTRY_ATTR_USER_DEFINED_FIELD_GROUP_\d+$/); + + $attr = "SAI_ACL_TABLE_ATTR_USER_DEFINED_FIELD_GROUP_MIN" + if ($attr =~ /^SAI_ACL_TABLE_ATTR_USER_DEFINED_FIELD_GROUP_\d+$/); + + if (not defined $ATTR_API_VER{$attr} and scalar(keys%ATTR_API_VER) != 0) + { + LogWarning "no version defined for $attr in saiattrversion.h"; + + return "SAI_VERSION(0,0,0)"; + } + + return "SAI_VERSION(0,0,0)" if not defined $ATTR_API_VER{$attr}; + + return "SAI_VERSION($1,$2,$3)" if $ATTR_API_VER{$attr} =~ /^v(\d+)\.(\d+)\.(\d+)$/; + + LogInfo "Setting $attr version to SAI_API_VERSION (future release)"; + + return "SAI_API_VERSION"; +} + +sub ProcessNextRelease +{ + my ($attr, $type) = @_; + + return "false" if not defined $ATTR_API_VER{$attr}; + + return "false" if $ATTR_API_VER{$attr} =~ /^v(\d+)\.(\d+)\.(\d+)$/; + + return "true"; +} + sub ProcessSingleObjectType { my ($typedef, $objecttype) = @_; @@ -2355,6 +2396,8 @@ sub ProcessSingleObjectType my $isresourcetype = ProcessIsResourceType($attr, $meta{isresourcetype}); my $isdeprecated = ProcessIsDeprecatedType($attr, $meta{deprecated}); my $isrelaxed = ProcessRelaxedType($attr, $meta{relaxed}); + my $apiversion = ProcessApiVersion($attr); + my $nextrelease = ProcessNextRelease($attr); my $ismandatoryoncreate = ($flags =~ /MANDATORY/) ? "true" : "false"; my $iscreateonly = ($flags =~ /CREATE_ONLY/) ? "true" : "false"; @@ -2413,7 +2456,8 @@ sub ProcessSingleObjectType WriteSource ".isresourcetype = $isresourcetype,"; WriteSource ".isdeprecated = $isdeprecated,"; WriteSource ".isconditionrelaxed = $isrelaxed,"; - WriteSource ".iscustom = ($attr >= 0x10000000) && ($attr < 0x20000000)"; + WriteSource ".apiversion = $apiversion,"; + WriteSource ".nextrelease = $nextrelease,"; WriteSource "};"; @@ -2467,6 +2511,15 @@ sub CreateMetadata } } +sub ProcessAttrVersion +{ + WriteSectionComment "Have attr versions"; + + my $count = scalar(keys%ATTR_API_VER); + + WriteHeader "#define SAI_METADATA_HAVE_ATTR_VERSION ($count)"; +} + sub ProcessSaiStatus { my $filename = "../inc/saistatus.h"; @@ -4371,6 +4424,24 @@ sub ExtractObjectTypeBulkMap %OBJECT_TYPE_BULK_MAP = %otmap; } +sub ExtractAttrApiVersion +{ + my $data = ReadHeaderFile("saiattrversion.h"); + + my @lines = split/\n/,$data; + + for my $line (@lines) + { + if (not $line =~ /#define (SAI_\w+_ATTR_\w+) "(v\d+\.\d+\.\d+|HEAD)"/) + { + LogError "invalid line in saiattrversion.h: $line"; + next; + } + + $ATTR_API_VER{$1} = $2; + } +} + sub CheckObjectTypeStatitics { # @@ -5534,6 +5605,8 @@ sub CreateDefineMaxConditionsLen ExtractStatsFunctionMap(); +ExtractAttrApiVersion(); + ExtractUnionsInfo(); CheckHeadersStyle() if not defined $optionDisableStyleCheck; @@ -5552,6 +5625,8 @@ sub CreateDefineMaxConditionsLen WriteHeaderHeader(); +ProcessAttrVersion(); + ProcessSaiStatus(); ProcessExtraRangeDefines(); diff --git a/meta/saimetadatatypes.h b/meta/saimetadatatypes.h index 551bf757c..e8ae8284c 100644 --- a/meta/saimetadatatypes.h +++ b/meta/saimetadatatypes.h @@ -1292,6 +1292,29 @@ typedef struct _sai_attr_metadata_t */ bool iscustom; + /** + * @brief Specifies API version at which attribute was introduced. + * + * If no version is available, then this value will be SAI_VERSION(0,0,0). + * + * This field should be used with nextrelease field. + */ + sai_api_version_t apiversion; + + /** + * @brief Specified whether attribute will be present in next API release. + * + * It may happen that there are new attributes defined after stable release, + * and they will be part of next release. In this case API version will + * have value of current API version and nextrelease set to true. + * + * For example, if attr is defined between v1.14 and v1.15, then API + * version will be v1.15 and next release is false. If attr is defined on + * top of v1.15 and there is not next release defined, then API version + * will be v1.15 and next release set to true. + */ + bool nextrelease; + } sai_attr_metadata_t; /* diff --git a/meta/saisanitycheck.c b/meta/saisanitycheck.c index fb76035a7..7b8fb880e 100644 --- a/meta/saisanitycheck.c +++ b/meta/saisanitycheck.c @@ -3470,6 +3470,27 @@ void check_attr_condition_relaxed( } } +void check_attr_version( + _In_ const sai_attr_metadata_t* md) +{ + META_LOG_ENTER(); + + if (SAI_METADATA_HAVE_ATTR_VERSION) + { + META_ASSERT_TRUE(md->apiversion > SAI_VERSION(0,0,0), "expected version to be defined"); + + if (md->nextrelease) + { + META_LOG_DEBUG("%s: nextrelease == true", md->attridname); + } + } + else + { + META_ASSERT_TRUE(md->apiversion == SAI_VERSION(0,0,0), "expected version to be zero"); + META_ASSERT_TRUE(md->nextrelease == false, "expected nextrelease to be false"); + } +} + void check_single_attribute( _In_ const sai_attr_metadata_t* md) { @@ -3517,6 +3538,7 @@ void check_single_attribute( check_attr_mixed_condition(md); check_attr_mixed_validonly(md); check_attr_condition_relaxed(md); + check_attr_version(md); define_attr(md); } diff --git a/meta/style.pm b/meta/style.pm index 7caa79839..9e1dea9f2 100644 --- a/meta/style.pm +++ b/meta/style.pm @@ -689,6 +689,7 @@ sub CheckMetadataSourceFiles next if $file eq "saimetadata.c"; next if $file eq "saimetadatatest.c"; next if $file eq "saimetadatasize.h"; + next if $file eq "saiattrversion.h"; next if $file eq "sai_rpc_server.cpp"; next if $file =~ /swig|wrap/; @@ -911,6 +912,7 @@ sub CheckHeadersStyle { next if $header eq "saimetadata.h"; # skip auto generated header next if $header eq "saimetadatasize.h"; # skip auto generated header + next if $header eq "saiattrversion.h"; # skip auto generated header my $data = ReadHeaderFile($header);