Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
647 changes: 647 additions & 0 deletions doc/SAI-Proposal-Numerical-Attribute-Value-Constraints.md

Large diffs are not rendered by default.

140 changes: 140 additions & 0 deletions inc/saiobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,146 @@ sai_status_t sai_query_object_stage(
_In_ const sai_attribute_t *attr_list,
_Out_ sai_object_stage_t *stage);

/**
* @brief Query value constraints for a numerical attribute.
*
* Returns the implementation-enforced value constraints (MIN / MAX /
* STEP / DEFAULT / ALLOWED_VALUES, see sai_attribute_constraint_type_t)
* for a numerical attribute on a given object type or object instance.
*
* The API is context-aware. The caller MAY pass a partial attribute
* list (attr_count + attr_list) that describes the sibling attribute
* values it intends to use for the (possibly yet-to-be-created)
* object. The implementation answers the constraint query as if the
* object were configured with those sibling attribute values. This is
* useful when the legal range of the queried attribute depends on the
* value of another (typically CREATE_ONLY) sibling attribute - for
* example, the legal range of SAI_POLICER_ATTR_CIR depends on
* SAI_POLICER_ATTR_METER_TYPE.
*
* Some constraints additionally depend on the HW pipeline stage at
* which the object will be applied, even though the stage is not
* represented as a sibling attribute on the object itself - for
* example, the legal range of
* SAI_MIRROR_SESSION_ATTR_TRUNCATE_SIZE may differ between ingress
* and egress mirror sessions, but the mirror session object has no
* direction attribute (the direction is established when the session
* is bound to a port via SAI_PORT_ATTR_INGRESS_MIRROR_SESSION /
* SAI_PORT_ATTR_EGRESS_MIRROR_SESSION). The optional stage parameter
* carries this context.
*
* The object_key, attr_list and stage parameters compose as follows:
*
* - If object_key is non-NULL, the constraints are computed for the
* referenced existing object. Sibling attribute values supplied via
* attr_list (if any) override the corresponding current values of
* the existing object for the purpose of this query.
*
* - If object_key is NULL and attr_list is non-empty, the constraints
* are computed for a hypothetical not-yet-created object of
* object_type configured with the sibling values from attr_list.
*
* - If object_key is NULL and attr_count is 0, the constraints are
* computed at the object-type level using attribute metadata
* defaults. Implementations MAY return SAI_STATUS_NOT_SUPPORTED when
* the answer depends on a sibling that has no default.
*
* - stage = SAI_OBJECT_STAGE_BOTH (zero) means stage-unspecified -
* the implementation returns stage-agnostic constraints (typically
* the intersection of the per-stage constraints, i.e. the most
* restrictive bounds that are safe at every stage). stage =
* SAI_OBJECT_STAGE_INGRESS / SAI_OBJECT_STAGE_EGRESS narrows the
* query to that pipeline stage. Implementations MUST accept
* SAI_OBJECT_STAGE_BOTH; the INGRESS / EGRESS selectors are
* honoured only when the queried attribute's constraints are
* actually stage-dependent (and otherwise behave identically to
* SAI_OBJECT_STAGE_BOTH).
*
* Standard two-pass sizing applies to the returned list, and also to
* any embedded list-valued constraint (ALLOWED_VALUES): the caller
* first issues the query with constraints->count = 0 and
* constraints->list = NULL (or with too-small buffers) to obtain the
* required sizes, then re-issues with buffers of those sizes.
*
* The API reports status on two channels. The function return value is
* the authoritative pass/fail for the whole call; it is
* SAI_STATUS_SUCCESS (or SAI_STATUS_BUFFER_OVERFLOW during sizing) only
* when the API ran and the (attr_id, attr_list, stage) combination is
* valid - any other value means constraints MUST NOT be consumed. The
* attr_status out-parameter carries the detailed combination verdict;
* for an invalid combination it holds the same code as the return
* value, and additionally (a) exposes, via the SAI_STATUS_..._0 + i
* ranges, the index i of the offending attr_list entry, and (b) reports
* combination validity independently of the buffer-sizing return state
* (SAI_STATUS_BUFFER_OVERFLOW maps to attr_status being SAI_STATUS_SUCCESS,
* because it reflects buffer capacity, not combination validity).
* bulk operations. attr_status is written whenever the API can run at
* all (i.e. the return value is neither SAI_STATUS_NOT_IMPLEMENTED nor
* SAI_STATUS_INVALID_PARAMETER), and is left untouched otherwise.
*
* A successful call that returns constraints->count == 0 is an explicit,
* valid answer: the implementation enforces no constraints on attr_id in
* this context (every value in the attribute's native type range is
* accepted). Over-supplying attr_list is harmless - a valid sibling that
* is irrelevant to attr_id is silently ignored and never causes an
* error; only siblings that are invalid for object_type
* (SAI_STATUS_INVALID_ATTRIBUTE_0 + i) or carry an out-of-range value
* (SAI_STATUS_INVALID_ATTR_VALUE_0 + i), or a sibling combination the
* implementation cannot evaluate (SAI_STATUS_ATTR_NOT_SUPPORTED_0 + i),
* are reported as errors.
*
* @param[in] switch_id SAI Switch object id
* @param[in] object_type SAI object type of the queried attribute
* @param[in] object_key Optional pointer to an existing object
* instance; may be NULL for object-type-level queries
* @param[in] attr_count Number of sibling-attribute context entries
* @param[in] attr_list Sibling-attribute context (may be NULL when
* attr_count is zero). Entries with attr_id equal to the
* queried attr_id are ignored, as are any valid siblings the
* implementation does not consider relevant to attr_id's
* constraints. The caller need not know which siblings matter:
* if unsure, it MAY pass all of the object's attributes and let
* the implementation pick out the relevant ones.
* @param[in] stage Optional pipeline-stage context. Pass
* SAI_OBJECT_STAGE_BOTH (zero) when the caller does not
* need to distinguish stages or when the attribute is not
* stage-dependent.
* @param[in] attr_id Numerical attribute id whose constraints are
* being queried. Must refer to an attribute whose
* attrvaluetype is a scalar integer (see
* sai_metadata_is_numerical_attr_value_type()).
* @param[inout] attr_status Status of the requested (attr_id,
* attr_list, stage) combination, encoded per saistatus.h. The
* pointer MUST be non-NULL. Carries the semantic result of the
* query, separate from the API-level return value: for an invalid
* combination it holds the same code as the return value (and, in
* the SAI_STATUS_..._0 + i ranges, the index i of the offending
* attr_list entry); on the buffer-sizing pass it is
* SAI_STATUS_SUCCESS even though the return value is
* SAI_STATUS_BUFFER_OVERFLOW. Only consume constraints when
* *attr_status is SAI_STATUS_SUCCESS.
* @param[inout] constraints Caller-allocated constraint list. On
* input constraints->count is the caller's buffer
* capacity; on output it is the actual (or required, on
* SAI_STATUS_BUFFER_OVERFLOW) number of entries.
*
* @return #SAI_STATUS_SUCCESS on success,
* #SAI_STATUS_BUFFER_OVERFLOW if any output buffer (the
* outer list or an inner ALLOWED_VALUES list) is too small
* (count fields are updated with the required sizes),
* failure status code on error.
*/
sai_status_t sai_query_attribute_value_constraints(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_In_ const sai_object_key_t *object_key,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list,
_In_ sai_object_stage_t stage,
_In_ sai_attr_id_t attr_id,
_Inout_ sai_status_t *attr_status,
_Inout_ sai_attribute_constraint_list_t *constraints);

/**
* @}
*/
Expand Down
118 changes: 118 additions & 0 deletions inc/saitypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,124 @@ typedef struct _sai_stat_capability_list_t

} sai_stat_capability_list_t;

/**
* @brief Kind of value constraint an implementation enforces on a
* numerical attribute.
*
* Carried in sai_attribute_constraint_t::type and returned by
* sai_query_attribute_value_constraints(). The accompanying
* sai_attribute_constraint_t::value MUST be interpreted using the
* QUERIED attribute's attrvaluetype (obtained via
* sai_metadata_get_attr_metadata() against the original object_type +
* attr_id) - this constraint-type enum is generic across all
* numerical attribute value types.
*/
typedef enum _sai_attribute_constraint_type_t
{
/**
* @brief Start of sai_attribute_constraint_type_t
*/
SAI_ATTRIBUTE_CONSTRAINT_TYPE_START,

/**
* @brief Minimum supported value (inclusive).
*/
SAI_ATTRIBUTE_CONSTRAINT_TYPE_MIN = SAI_ATTRIBUTE_CONSTRAINT_TYPE_START,

/**
* @brief Maximum supported value (inclusive).
*/
SAI_ATTRIBUTE_CONSTRAINT_TYPE_MAX,

/**
* @brief Granularity (step). Legal values form the arithmetic
* progression { min + k * step } intersected with [min, max].
*/
SAI_ATTRIBUTE_CONSTRAINT_TYPE_STEP,

/**
* @brief Implementation-specific default value when it differs
* from the default declared in the attribute metadata.
*/
SAI_ATTRIBUTE_CONSTRAINT_TYPE_DEFAULT,

/**
* @brief Discrete set of allowed values. The value carrier is a
* list (u8list / s8list / u16list / s16list / u32list / s32list)
* selected by the queried attribute's attrvaluetype; standard
* two-pass sizing applies to the embedded list buffer.
*/
SAI_ATTRIBUTE_CONSTRAINT_TYPE_ALLOWED_VALUES,

/** End of sai_attribute_constraint_type_t */
SAI_ATTRIBUTE_CONSTRAINT_TYPE_END

} sai_attribute_constraint_type_t;

/**
* @brief One value-constraint entry.
*
* The (type, value) tuple advertises one constraint the implementation
* enforces on the queried numerical attribute. The value field is
* interpreted using the QUERIED attribute's attrvaluetype, not the
* constraint-type enum.
*
* For scalar constraints (MIN, MAX, STEP, DEFAULT) read the scalar
* union member of sai_attribute_value_t that matches the queried
* attrvaluetype (u8, s8, u16, s16, u32, s32, u64 or s64).
*
* For the ALLOWED_VALUES constraint, read the matching list union
* member (u8list, s8list, u16list, s16list, u32list or s32list).
* The caller pre-allocates the embedded list buffer using the
* standard SAI two-pass sizing protocol.
*
* @extraparam const sai_attr_metadata_t *meta
*/
typedef struct _sai_attribute_constraint_t
{
/**
* @brief Kind of constraint.
*/
sai_attribute_constraint_type_t type;

/**
* @brief Constraint value, interpreted using the QUERIED
* attribute's attrvaluetype.
*
* @passparam meta
*/
sai_attribute_value_t value;

} sai_attribute_constraint_t;

/**
* @brief List of value-constraint entries returned by
* sai_query_attribute_value_constraints().
*
* Standard SAI two-pass sizing: the caller first invokes the query
* with count = 0 and list = NULL to obtain the required count, then
* re-invokes with a buffer of that size.
*
* @extraparam const sai_attr_metadata_t *meta
*/
typedef struct _sai_attribute_constraint_list_t
{
/**
* @brief In: caller's buffer capacity in entries.
* Out: actual (or required, on SAI_STATUS_BUFFER_OVERFLOW)
* number of constraint entries.
*/
uint32_t count;

/**
* @brief Caller-allocated array of length count.
*
* @passparam meta
*/
sai_attribute_constraint_t *list;

} sai_attribute_constraint_list_t;

/**
* @brief Stat capability under the stream telemetry mode
*/
Expand Down
12 changes: 12 additions & 0 deletions meta/libsai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ sai_status_t sai_query_attribute_enum_values_capability(
_Inout_ sai_s32_list_t *enum_values_capability)
{ return SAI_STATUS_NOT_IMPLEMENTED; }

sai_status_t sai_query_attribute_value_constraints(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_In_ const sai_object_key_t *object_key,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list,
_In_ sai_object_stage_t stage,
_In_ sai_attr_id_t attr_id,
_Inout_ sai_status_t *attr_status,
_Inout_ sai_attribute_constraint_list_t *constraints)
{ return SAI_STATUS_NOT_IMPLEMENTED; }

sai_status_t sai_query_object_stage(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
Expand Down
20 changes: 20 additions & 0 deletions meta/saimetadatautils.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,3 +614,23 @@ sai_api_version_t sai_metadata_query_api_version(void)
{
return SAI_API_VERSION;
}

bool sai_metadata_is_numerical_attr_value_type(
_In_ sai_attr_value_type_t attrvaluetype)
{
switch (attrvaluetype)
{
case SAI_ATTR_VALUE_TYPE_UINT8:
case SAI_ATTR_VALUE_TYPE_INT8:
case SAI_ATTR_VALUE_TYPE_UINT16:
case SAI_ATTR_VALUE_TYPE_INT16:
case SAI_ATTR_VALUE_TYPE_UINT32:
case SAI_ATTR_VALUE_TYPE_INT32:
case SAI_ATTR_VALUE_TYPE_UINT64:
case SAI_ATTR_VALUE_TYPE_INT64:
return true;

default:
return false;
}
}
16 changes: 16 additions & 0 deletions meta/saimetadatautils.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,22 @@ extern bool sai_metadata_is_validonly_met(
*/
extern sai_api_version_t sai_metadata_query_api_version(void);

/**
* @brief Tests whether an attrvaluetype is a scalar numerical integer
* type that is a candidate for sai_query_attribute_value_constraints().
*
* Returns true for SAI_ATTR_VALUE_TYPE_UINT8 / UINT16 / UINT32 / UINT64
* and SAI_ATTR_VALUE_TYPE_INT8 / INT16 / INT32 / INT64. Returns false
* for boolean, pointer, MAC, IP, list, range and aggregate types.
*
* @param[in] attrvaluetype Attribute value type to be checked.
*
* @return True if attrvaluetype is a scalar numerical integer type,
* false otherwise.
*/
extern bool sai_metadata_is_numerical_attr_value_type(
_In_ sai_attr_value_type_t attrvaluetype);

/**
* @}
*/
Expand Down
2 changes: 2 additions & 0 deletions meta/saisanitycheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -6334,6 +6334,8 @@ void check_struct_and_union_size()
CHECK_STRUCT_SIZE(sai_acl_resource_list_t, 16);
CHECK_STRUCT_SIZE(sai_acl_resource_t, 12);
CHECK_STRUCT_SIZE(sai_attr_capability_t, 3);
CHECK_STRUCT_SIZE(sai_attribute_constraint_list_t, 16);
CHECK_STRUCT_SIZE(sai_attribute_constraint_t, 48);
CHECK_STRUCT_SIZE(sai_attribute_t, 48);
CHECK_STRUCT_SIZE(sai_bfd_session_state_notification_t, 16);
CHECK_STRUCT_SIZE(sai_fabric_port_reachability_t, 8);
Expand Down
Loading