Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class-Based Forwarding #1193

Merged
merged 20 commits into from
Aug 27, 2021
Merged
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
211 changes: 211 additions & 0 deletions doc/ECMP/Class-Based-Forwarding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# Class-based Forwarding

Title | Class-based Forwarding
------------|----------------
Authors | Cisco
Status | In review
Type | Standards track
Created | 04/14/2021
SAI-Version | 1.8

Class-based forwarding provides a method to steer traffic among multiple paths through the network by policy rather than, or in combination with, traditional ECMP/UCMP flow-hashing.

A new type of next-hop group is introduced:

```
typedef enum _sai_next_hop_group_type_t
{
...
/** Next hop group is class-based, with members selected by Forwarding class */
SAI_NEXT_HOP_GROUP_TYPE_CLASS_BASED,
...
} sai_next_hop_group_type_t;
```

The behavior of SAI_NEXT_HOP_GROUP_TYPE_CLASS_BASED differs from the traditional SAI_NEXT_HOP_GROUP_TYPE_ECMP, in that each packet will have a Forwarding class that chooses next-hop group member index.

This is accomplished by directly mapping each forwarding class to the group member index, via map configured to the next-hop group object.

```
/**
* @brief Member selection map
*
* @type sai_object_id_t
* @flags CREATE_AND_SET
* @objects SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MAP
* @allownull true
* @default SAI_NULL_OBJECT_ID
* @validonly SAI_NEXT_HOP_GROUP_ATTR_TYPE == SAI_NEXT_HOP_GROUP_TYPE_CLASS_BASED
*/
SAI_NEXT_HOP_GROUP_ATTR_SELECTION_MAP,
```
j-bos marked this conversation as resolved.
Show resolved Hide resolved

If a packet arrives with a forwarding-class which is not present in the map, the chosen index shall be 0.

```
typedef enum _sai_next_hop_group_member_attr_t
{
...
/**
* @brief Object index in the next-hop group.
*
* Index specifying the strict member's order.
* Allowed value range for is from 0 to SAI_NEXT_HOP_GROUP_ATTR_REAL_SIZE - 1.
* Should only be used if the type of owning group is SAI_NEXT_HOP_GROUP_TYPE_FINE_GRAIN_ECMP
* or SAI_NEXT_HOP_GROUP_TYPE_CLASS_BASED.
*
* @type sai_uint32_t
* @flags CREATE_ONLY
* @default 0
*/
SAI_NEXT_HOP_GROUP_MEMBER_ATTR_INDEX,
...
} sai_next_hop_group_member_attr_t;
```

If the map selects an index for which a member does not exist, the packet shall be treated as having a next-hop of SAI_NULL_OBJECT_ID, dropping the packet.

Members of type next-hop or next-hop groups of type ECMP shall be allowed. To allow this, next-hop group member type is extended to allow other next-hop groups:

```
/**
* @brief Next hop id
*
* @type sai_object_id_t
* @flags MANDATORY_ON_CREATE | CREATE_AND_SET
* @objects SAI_OBJECT_TYPE_NEXT_HOP, <b>SAI_OBJECT_TYPE_NEXT_HOP_GROUP</b>
*/
SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID,
```

*Note: While this would also be a means to configure a hierarchical ECMP, hierarchical ECMP is outside the scope of this proposal.*

The forwarding-class for a packet may be selected via qos-map or ACL.

```
typedef enum _sai_qos_map_type_t
{
...
/** QOS Map to set DSCP to Forwarding class */
SAI_QOS_MAP_TYPE_DSCP_TO_FORWARDING_CLASS = 0x0000000d,

/** QOS Map to set EXP to Forwarding class */
SAI_QOS_MAP_TYPE_MPLS_EXP_TO_FORWARDING_CLASS = 0x0000000e,
...
} sai_qos_map_type_t;
```

```
typedef enum _sai_acl_entry_attr_t
...
/**
* @brief Set Forwarding Class
*
* @type sai_acl_action_data_t sai_uint8_t
* @flags CREATE_AND_SET
* @default disabled
*/
SAI_ACL_ENTRY_ATTR_ACTION_SET_FORWARDING_CLASS,
...
} sai_acl_entry_attr_t;
```

j-bos marked this conversation as resolved.
Show resolved Hide resolved
If the packet is not assigned a forwarding-class, then the forwarding-class of the packet shall be 0. For example, if no qos-map or ACL is configured. Normal QOS/ACL precedence rules apply; if supported by the implementation, the ACL would override the QOS MAP decision.

*Resource monitoring considerations:*

The attribute SAI_SWITCH_ATTR_MAX_NUMBER_OF_FORWARDING_CLASSES may be used to identify the maximum forwarding-class allowed.

The SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MAP object is a resource. The sai_object_type_get_availability() API may be used to query the maximum number of permitted maps.

*Class-based forwarding group configuration example:*
```
/******************************************************
* Create a forwarding-class -> index map.
* In this example, map 8 forwarding-classes to 2 members.
* FC 0-5 -> index 0
* FC 6-7 -> index 1
******************************************************/
const int num_forwarding_classes = 8;
const int num_members = 2;

sai_object_id_t nh_group_map;

sai_map_t fc_map[num_forwarding_classes];
for (int fc = 0; fc < num_forwarding_classes; ++fc) {
fc_map[fc].key = fc;
if (fc >= 6) {
fc_map[fc].value = 1;
} else {
fc_map[fc].value = 0;
}
}

sai_map_list_t fc_map_list;
fc_map_list.key.count = num_forwarding_classes;
fc_map_list.key.list = fc_map;

attr.id = SAI_NEXT_HOP_GROUP_MAP_ATTR_TYPE;
attr.value.u32 = SAI_NEXT_HOP_GROUP_MAP_TYPE_FORWARDING_CLASS_TO_INDEX;
attrs.push_back(attr);

attr.id = SAI_NEXT_HOP_GROUP_MAP_ATTR_MAP_TO_VALUE_LIST;
attr.value.maplist = fc_map_list;
attrs.push_back(attr);

sai_next_hop_group_api->create_next_hop_group_map(
&nh_group_map,
g_switch_id,
attrs.size(),
attrs.data());

/*****************************************************
* Create a class-based forwarding group
*****************************************************/
attrs.clear();

sai_object_id_t nh_group;

attr.id = SAI_NEXT_HOP_GROUP_ATTR_TYPE;
attr.value.u32 = SAI_NEXT_HOP_GROUP_TYPE_CLASS_BASED;
attrs.push_back(attr);

attr.id = SAI_NEXT_HOP_GROUP_ATTR_CONFIGURED_SIZE;
attr.value.u32 = num_members;
attrs.push_back(attr);

attr.id = SAI_NEXT_HOP_GROUP_ATTR_SELECTION_MAP;
attr.value.oid = nh_group_map;
attrs.push_back(attr);

sai_next_hop_group_api->create_next_hop_group(
&nh_group,
g_switch_id,
attrs.size(),
attrs.data());

/*****************************************************
* Create members
*****************************************************/
attrs.clear();

for (index = 0; index < num_members; ++index) {
attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID;
attr.value.oid = nh_group;
attrs.push_back(attr);

attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID;
attr.value.oid = destinations[index]; // Next-hop or ECMP group
attrs.push_back(attr);

attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_INDEX;
attr.value.u32 = index;
attrs.push_back(attr);

sai_next_hop_group_api->create_next_hop_group_member(
&members[member_index],
g_switch_id,
attrs.size(),
attrs.data());
}
```
Binary file added doc/behavioral model/pipeline_v9.vsdx
Binary file not shown.
16 changes: 14 additions & 2 deletions inc/saiacl.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,10 @@ typedef enum _sai_acl_action_type_t
SAI_ACL_ACTION_TYPE_SET_ECMP_HASH_ID = 0x00000030,

/** Associate with virtual router */
SAI_ACL_ACTION_TYPE_SET_VRF = 0x00000031
SAI_ACL_ACTION_TYPE_SET_VRF = 0x00000031,

/** Set Forwarding class */
SAI_ACL_ACTION_TYPE_SET_FORWARDING_CLASS = 0x00000034,
kcudnik marked this conversation as resolved.
Show resolved Hide resolved

} sai_acl_action_type_t;

Expand Down Expand Up @@ -2922,10 +2925,19 @@ typedef enum _sai_acl_entry_attr_t
*/
SAI_ACL_ENTRY_ATTR_ACTION_SET_VRF = SAI_ACL_ENTRY_ATTR_ACTION_START + 0x31,

/**
* @brief Set Forwarding Class
*
* @type sai_acl_action_data_t sai_uint8_t
* @flags CREATE_AND_SET
* @default disabled
*/
SAI_ACL_ENTRY_ATTR_ACTION_SET_FORWARDING_CLASS = SAI_ACL_ENTRY_ATTR_ACTION_START + 0x34,

/**
* @brief End of Rule Actions
*/
SAI_ACL_ENTRY_ATTR_ACTION_END = SAI_ACL_ENTRY_ATTR_ACTION_ADD_VLAN_PRI,
SAI_ACL_ENTRY_ATTR_ACTION_END = SAI_ACL_ENTRY_ATTR_ACTION_SET_FORWARDING_CLASS,

/**
* @brief End of ACL Entry attributes
Expand Down
Loading