Skip to content

Commit

Permalink
Fix serialize/deseralize functions in SAI meta (#1807)
Browse files Browse the repository at this point in the history
This PR is fixing several issues we saw in serialize/deserialize:

1 Fix several not implemented deserialize functions.
sai_deserialize_enum_list()
sai_deserialize_attr_id()
sai_deserialize_attribute()
By doing this, the serialize/deserialize functions are complete.

2 Mark several attributes as aclfiled for SAI_OBJECT_TYPE_UDF_MATCH. The corresponding attribute values are in type of sai_acl_field_data_t.
SAI_UDF_MATCH_ATTR_L2_TYPE ~ SAI_UDF_MATCH_ATTR_GRE_TYPE
SAI_UDF_MATCH_ATTR_L4_DST_PORT_TYPE
By doing this, serialize/deserialize for the above attributes works as expected.

3 Add sai_metadata_get_attr_metadata_by_attr_id_name_ext which can support the case of attribute id name is in deserialized buffer and terminated by characters listed in function sai_serialize_is_char_allowed().
By doing this, sai_deserialize_attr_id() and sai_deserialize_attribute() can get the attribute metadata by the deserialized buffer.

4 Return SAI_SERIALIZE_ERROR in case of the data type is not find for the attribute value.
By doing this, the user can know that serialize/deserialize is failed and do proper response

Signed-off-by: Juntao Gao <[email protected]>
  • Loading branch information
juntaog authored Jul 7, 2023
1 parent 708d3fb commit c48d0b8
Show file tree
Hide file tree
Showing 7 changed files with 447 additions and 17 deletions.
2 changes: 2 additions & 0 deletions meta/parse.pl
Original file line number Diff line number Diff line change
Expand Up @@ -2056,6 +2056,8 @@ sub ProcessIsAclField

return "true" if $attr =~ /^SAI_ACL_ENTRY_ATTR_(USER_DEFINED_)?FIELD_\w+$/;

return "true" if $attr =~ /^SAI_UDF_MATCH_ATTR_\w+_TYPE$/;

return "false";
}

Expand Down
69 changes: 69 additions & 0 deletions meta/saimetadatautils.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,75 @@ const sai_attr_metadata_t* sai_metadata_get_attr_metadata_by_attr_id_name(
return NULL;
}

static int sai_metadata_attr_id_name_cmp(
_In_ const char * str1,
_In_ const char * str2)
{
char c1 = 0;
char c2 = 0;

while (true)
{
c1 = *str1++;
c2 = *str2++;

if (sai_serialize_is_char_allowed(c1) || sai_serialize_is_char_allowed(c2) || c1 != c2)
{
if (sai_serialize_is_char_allowed(c1))
{
c1 = 0;
}

if (sai_serialize_is_char_allowed(c2))
{
c2 = 0;
}

return c1 - c2;
}
}
}

const sai_attr_metadata_t* sai_metadata_get_attr_metadata_by_attr_id_name_ext(
_In_ const char *attr_id_name)
{
if (attr_id_name == NULL)
{
return NULL;
}

/* use binary search */

ssize_t first = 0;
ssize_t last = (ssize_t)(sai_metadata_attr_sorted_by_id_name_count - 1);

while (first <= last)
{
ssize_t middle = (first + last) / 2;

int res = sai_metadata_attr_id_name_cmp(attr_id_name, sai_metadata_attr_sorted_by_id_name[middle]->attridname);

if (res > 0)
{
first = middle + 1;
}
else if (res < 0)
{
last = middle - 1;
}
else
{
/* found */

return sai_metadata_attr_sorted_by_id_name[middle];
}
}

/* not found */

return NULL;
}

const sai_attr_metadata_t* sai_metadata_get_ignored_attr_metadata_by_attr_id_name(
_In_ const char *attr_id_name)
{
Expand Down
12 changes: 12 additions & 0 deletions meta/saimetadatautils.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ extern const sai_attr_metadata_t* sai_metadata_get_attr_metadata(
extern const sai_attr_metadata_t* sai_metadata_get_attr_metadata_by_attr_id_name(
_In_ const char *attr_id_name);

/**
* @brief Gets attribute metadata based on attribute id name, supporting case of
* attribute id name is in deserialized buffer and terminated by characters listed
* in function sai_serialize_is_char_allowed.
*
* @param[in] attr_id_name Attribute id name
*
* @return Pointer to object metadata or NULL in case of failure
*/
extern const sai_attr_metadata_t* sai_metadata_get_attr_metadata_by_attr_id_name_ext(
_In_ const char *attr_id_name);

/**
* @brief Gets ignored attribute metadata based on attribute id name
*
Expand Down
63 changes: 54 additions & 9 deletions meta/saisanitycheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,19 @@ bool sai_metadata_is_acl_field_or_action(
}
}

if (metadata->objecttype == SAI_OBJECT_TYPE_UDF_MATCH)
{
if (metadata->attrid <= SAI_UDF_MATCH_ATTR_GRE_TYPE)
{
return true;
}

if (metadata->attrid == SAI_UDF_MATCH_ATTR_L4_DST_PORT_TYPE)
{
return true;
}
}

return false;
}

Expand Down Expand Up @@ -2328,26 +2341,44 @@ void check_attr_acl_field_or_action(
META_ASSERT_FALSE(md->defaultvalue->aclaction.enable, "enable should be false");
}

if (md->objecttype != SAI_OBJECT_TYPE_ACL_ENTRY)
if (md->objecttype != SAI_OBJECT_TYPE_ACL_ENTRY && md->objecttype != SAI_OBJECT_TYPE_UDF_MATCH)
{
META_ASSERT_FALSE(md->isaclfield, "field should be not marked as acl field");
META_ASSERT_FALSE(md->isaclaction, "field should be not marked as acl action");

return;
}

if (md->attrid >= SAI_ACL_ENTRY_ATTR_FIELD_START &&
md->attrid <= SAI_ACL_ENTRY_ATTR_FIELD_END)
if (md->objecttype == SAI_OBJECT_TYPE_ACL_ENTRY)
{
META_ASSERT_TRUE(md->isaclfield, "field should be marked as acl field");
META_ASSERT_FALSE(md->isaclaction, "field should be not marked as acl action");
if (md->attrid >= SAI_ACL_ENTRY_ATTR_FIELD_START &&
md->attrid <= SAI_ACL_ENTRY_ATTR_FIELD_END)
{
META_ASSERT_TRUE(md->isaclfield, "field should be marked as acl field");
META_ASSERT_FALSE(md->isaclaction, "field should be not marked as acl action");
}

if (md->attrid >= SAI_ACL_ENTRY_ATTR_ACTION_START &&
md->attrid <= SAI_ACL_ENTRY_ATTR_ACTION_END)
{
META_ASSERT_FALSE(md->isaclfield, "field should not be marked as acl field");
META_ASSERT_TRUE(md->isaclaction, "field should be marked as acl action");
}
}

if (md->attrid >= SAI_ACL_ENTRY_ATTR_ACTION_START &&
md->attrid <= SAI_ACL_ENTRY_ATTR_ACTION_END)
if (md->objecttype == SAI_OBJECT_TYPE_UDF_MATCH)
{
META_ASSERT_FALSE(md->isaclfield, "field should not be marked as acl field");
META_ASSERT_TRUE(md->isaclaction, "field should be marked as acl action");
if (md->attrid <= SAI_UDF_MATCH_ATTR_GRE_TYPE)
{
META_ASSERT_TRUE(md->isaclfield, "field should be marked as acl field");
META_ASSERT_FALSE(md->isaclaction, "field should be not marked as acl action");
}

if (md->attrid == SAI_UDF_MATCH_ATTR_L4_DST_PORT_TYPE)
{
META_ASSERT_TRUE(md->isaclfield, "field should be marked as acl field");
META_ASSERT_FALSE(md->isaclaction, "field should be not marked as acl action");
}
}
}

Expand Down Expand Up @@ -3760,6 +3791,13 @@ void check_attr_sorted_by_id_name()
META_ASSERT_NOT_NULL(found);

META_ASSERT_TRUE(strcmp(found->attridname, am->attridname) == 0, "search attr by id name failed to find");

const sai_attr_metadata_t *found_ext = sai_metadata_get_attr_metadata_by_attr_id_name_ext(am->attridname);

META_ASSERT_NOT_NULL(found_ext);

META_ASSERT_TRUE(strcmp(found_ext->attridname, am->attridname) == 0, "search attr by id name ext failed to find");

}

META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name(NULL)); /* null pointer */
Expand All @@ -3768,6 +3806,13 @@ void check_attr_sorted_by_id_name()
META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name("SAI_P")); /* in the middle of attr names */
META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name("SAI_W")); /* in the middle of attr names */
META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name("ZZZ")); /* after all attr names */

META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name_ext(NULL)); /* null pointer */
META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name_ext("AAA")); /* before all attr names */
META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name_ext("SAI_B")); /* in the middle of attr names */
META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name_ext("SAI_P")); /* in the middle of attr names */
META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name_ext("SAI_W")); /* in the middle of attr names */
META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name_ext("ZZZ")); /* after all attr names */
}

void list_loop(
Expand Down
125 changes: 117 additions & 8 deletions meta/saiserialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sai.h>
#include "saimetadatautils.h"
#include "saimetadata.h"
Expand All @@ -38,6 +39,24 @@
#define PRIMITIVE_BUFFER_SIZE 128
#define MAX_CHARS_PRINT 25

/* Expect macros */

#define EXPECT(x) { \
if (strncmp(buf, x, sizeof(x) - 1) == 0) { buf += sizeof(x) - 1; } \
else { \
SAI_META_LOG_WARN("expected '%s' but got '%.*s...'", x, (int)sizeof(x), buf); \
return SAI_SERIALIZE_ERROR; } }
#define EXPECT_KEY(k) EXPECT("\"" k "\":")
#define EXPECT_NEXT_KEY(k) { EXPECT(","); EXPECT_KEY(k); }
#define EXPECT_CHECK(expr, suffix) { \
ret = (expr); \
if (ret < 0) { \
SAI_META_LOG_WARN("failed to deserialize " #suffix ""); \
return SAI_SERIALIZE_ERROR; } \
buf += ret; }
#define EXPECT_QUOTE_CHECK(expr, suffix) {\
EXPECT("\""); EXPECT_CHECK(expr, suffix); EXPECT("\""); }

bool sai_serialize_is_char_allowed(
_In_ char c)
{
Expand Down Expand Up @@ -1154,8 +1173,8 @@ int sai_serialize_enum_list(
SAI_META_LOG_WARN("failed to serialize enum_list");
return SAI_SERIALIZE_ERROR;
}
buf += ret;

buf += ret;
buf += sprintf(buf, "\"");
}

Expand All @@ -1172,25 +1191,83 @@ int sai_deserialize_enum_list(
_In_ const sai_enum_metadata_t *meta,
_Out_ sai_s32_list_t *list)
{
SAI_META_LOG_WARN("not implemented");
return SAI_SERIALIZE_ERROR;
if (meta == NULL)
{
return sai_deserialize_s32_list(buffer, list);
}

const char *buf = buffer;
int ret;
uint32_t idx;

EXPECT("{");

EXPECT_KEY("count");

EXPECT_CHECK(sai_deserialize_uint32(buf, &list->count), uint32);

EXPECT_NEXT_KEY("list");

if (strncmp(buf, "null", 4) == 0)
{
list->list = NULL;

buf += 4;
}
else
{
list->list = calloc((list->count), sizeof(uint32_t));

EXPECT("[");

for (idx = 0; idx < list->count; idx++)
{
if (idx != 0)
{
EXPECT(",");
}

EXPECT_QUOTE_CHECK(sai_deserialize_enum(buf, meta, &list->list[idx]), enum);
}

EXPECT("]");
}

EXPECT("}");

return (int)(buf - buffer);
}

int sai_serialize_attr_id(
_Out_ char *buf,
_In_ const sai_attr_metadata_t *meta,
_In_ sai_attr_id_t attr_id)
{
strcpy(buf, meta->attridname);
if (meta != NULL)
{
strcpy(buf, meta->attridname);
return (int)strlen(buf);
}

return (int)strlen(buf);
SAI_META_LOG_WARN("failed to serialize attr_id");
return SAI_SERIALIZE_ERROR;
}

int sai_deserialize_attr_id(
_In_ const char *buffer,
_Out_ sai_attr_id_t *attr_id)
{
SAI_META_LOG_WARN("not implemented");
const sai_attr_metadata_t *meta;

meta = sai_metadata_get_attr_metadata_by_attr_id_name_ext(buffer);

if (meta != NULL)
{
*attr_id = meta->attrid;
return (int)strlen(meta->attridname);
}

SAI_META_LOG_WARN("failed to deserialize attr_id");
return SAI_SERIALIZE_ERROR;
}

Expand Down Expand Up @@ -1243,6 +1320,38 @@ int sai_deserialize_attribute(
_In_ const char *buffer,
_Out_ sai_attribute_t *attribute)
{
SAI_META_LOG_WARN("not implemented");
return SAI_SERIALIZE_ERROR;
const char *buf = buffer;
const sai_attr_metadata_t *meta;
size_t len;
int ret;

EXPECT("{");

EXPECT_KEY("id");

EXPECT("\"");

meta = sai_metadata_get_attr_metadata_by_attr_id_name_ext(buf);

if (meta != NULL)
{
len = strlen(meta->attridname);
attribute->id = meta->attrid;
buf += len;
}
else
{
SAI_META_LOG_WARN("Failed deserialize attribute id");
return SAI_SERIALIZE_ERROR;
}

EXPECT("\"");

EXPECT_NEXT_KEY("value");

EXPECT_CHECK(sai_deserialize_attribute_value(buf, meta, &attribute->value), "attr_value");

EXPECT("}");

return (int)(buf - buffer);
}
Loading

0 comments on commit c48d0b8

Please sign in to comment.