From e53813c0f8965847ea5baf37411b453da6723494 Mon Sep 17 00:00:00 2001 From: erohsik <71034063+erohsik@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:31:55 -0800 Subject: [PATCH] Next hop group with members. (#2013) * Next hop group with members. Introduce a new type of Next hop group that allows the application to provide the list of next hops that are members of the Next hop group along with the list of weights. Signed-off-by: Kishore Gummadidala Co-authored-by: Kishore Gummadidala Signed-off-by: Kumaresh Perumal --- doc/ECMP/NextHopGroup_with_members.md | 85 +++++++++++++++++++++++++++ inc/sainexthopgroup.h | 46 +++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 doc/ECMP/NextHopGroup_with_members.md diff --git a/doc/ECMP/NextHopGroup_with_members.md b/doc/ECMP/NextHopGroup_with_members.md new file mode 100644 index 000000000..9378a433a --- /dev/null +++ b/doc/ECMP/NextHopGroup_with_members.md @@ -0,0 +1,85 @@ +### Next hop group with members + +Introduce a new type of Next hop group, that is created/modified by specifying the list of next hop members along with their weights. + +### Motivation + +The existing workflow to create Next hop groups involves these steps +* Create a Next hop group +* Add next hop to this group + +Next hop groups can be modified by +* Removing existing next hop group members +* Modifying attributes of existing next hop group members +* Adding new next hop group members + +This multi-step process to modify Next hop groups can lead to the Next hop group to be in intermediate state(s) before finally matching the application intent. The sequence of add/modify/delete must ensure that the number of next hop group members do not exceed the maximum size of the Next hop group. The group should not be unintentionally empty. This sequence may lead to the Next hop group to have less forwarding capacity in the intermediate states. + +If we could instead specify the current list of next hop group members, we could modify the Next hop group in one step. + +### Proposal + +* Introduce a new type of Next hop group +* Add a new Next hop group attribute for the list of Next hops +* Add a new Next hop group attribute for the list of weights +* Create/modify the Next hop group by specifying both of the above lists + +No next hop group member objects will be created in this workflow. +Any modification of the next hop group will need the application to pass in the +current list of next hops. +The member next hops need not be removed before removing the next hop group. + +### Example + +Create a next hop group. + +``` + std::vector nh_oids{nh1, nh2, nh3}; + std::vector weights{1, 2, 1}; + std::vector group_attr; + + attr.id = SAI_NEXT_HOP_GROUP_ATTR_TYPE; + attr.value.s32 = SAI_NEXT_HOP_GROUP_TYPE_ECMP_WITH_MEMBERS; + group_attr.push_back(attr); + + attr.id = SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_MEMBER_WEIGHT_LIST; + attr.value.u32list.count = (uint32_t)weights.size(); + attr.value.u32list.list = weights.data(); + group_attr.push_back(attr); + + attr.id = SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_LIST; + attr.value.objlist.count = (uint32_t)nh_oids.size(); + attr.value.objlist.list = nh_oids.data(); + group_attr.push_back(attr); + + sai_status_t status = + sai_next_hop_group_api->create_next_hop_group(&group_oid, switchid, + (uint32_t)group_attr.size(), group_attr.data()); +``` + +Modify follows the same pattern by specifying the new list of next hops and weights via the bulk set api + +``` + std::vector nh_oids{nh1, nh3, nh4}; + std::vector weights{1, 2, 3}; + std::vector group_attr; + std::vector nhg_oids{nhg1, nhg1}; + std::vector statuses; + + attr.id = SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_MEMBER_WEIGHT_LIST; + attr.value.u32list.count = (uint32_t)weights.size(); + attr.value.u32list.list = weights.data(); + group_attr.push_back(attr); + + attr.id = SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_LIST; + attr.value.objlist.count = (uint32_t)nh_oids.size(); + attr.value.objlist.list = nh_oids.data(); + group_attr.push_back(attr); + + sai_status_t status = + sai_next_hop_group_api->set_next_hop_groups_attribute( + (uint32_t)nhg_oids.size(), + nhg_oids.data(), group_attr.data(), + SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, + statuses.data()); +``` diff --git a/inc/sainexthopgroup.h b/inc/sainexthopgroup.h index d591e2466..94626d6f9 100644 --- a/inc/sainexthopgroup.h +++ b/inc/sainexthopgroup.h @@ -59,6 +59,9 @@ typedef enum _sai_next_hop_group_type_t /** Next hop hardware protection group. This is the group backing up the primary in the protection group type and is managed by hardware */ SAI_NEXT_HOP_GROUP_TYPE_HW_PROTECTION, + /** Next hop group is ECMP, with members specified with the group */ + SAI_NEXT_HOP_GROUP_TYPE_ECMP_WITH_MEMBERS, + /* Other types of next hop group to be defined in the future, e.g., WCMP */ } sai_next_hop_group_type_t; @@ -110,6 +113,8 @@ typedef enum _sai_next_hop_group_attr_t /** * @brief Next hop member list * + * Not valid when SAI_NEXT_HOP_GROUP_ATTR_TYPE == SAI_NEXT_HOP_GROUP_TYPE_ECMP_WITH_MEMBERS + * * @type sai_object_list_t * @flags READ_ONLY * @objects SAI_OBJECT_TYPE_NEXT_HOP_GROUP_MEMBER @@ -235,6 +240,42 @@ typedef enum _sai_next_hop_group_attr_t */ SAI_NEXT_HOP_GROUP_ATTR_ARS_PORT_REASSIGNMENTS, + /** + * @brief Next hop member list in the order specified by the application + * + * NH OID list length should match weight list length + * + * @type sai_object_list_t + * @flags CREATE_AND_SET + * @objects SAI_OBJECT_TYPE_NEXT_HOP + * @default empty + * @validonly SAI_NEXT_HOP_GROUP_ATTR_TYPE == SAI_NEXT_HOP_GROUP_TYPE_ECMP_WITH_MEMBERS + */ + SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_LIST, + + /** + * @brief Next hop member weight list + * + * @type sai_u32_list_t + * @flags CREATE_AND_SET + * @default empty + * @validonly SAI_NEXT_HOP_GROUP_ATTR_TYPE == SAI_NEXT_HOP_GROUP_TYPE_ECMP_WITH_MEMBERS + */ + SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_MEMBER_WEIGHT_LIST, + + /** + * @brief Next hop member counter list + * + * When it is empty, then packet hits won't be counted + * + * @type sai_object_list_t + * @flags CREATE_AND_SET + * @objects SAI_OBJECT_TYPE_COUNTER + * @default empty + * @validonly SAI_NEXT_HOP_GROUP_ATTR_TYPE == SAI_NEXT_HOP_GROUP_TYPE_ECMP_WITH_MEMBERS + */ + SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_MEMBER_COUNTER_LIST, + /** * @brief End of attributes */ @@ -610,6 +651,11 @@ typedef struct _sai_next_hop_group_api_t sai_get_next_hop_group_map_attribute_fn get_next_hop_group_map_attribute; sai_bulk_object_set_attribute_fn set_next_hop_group_members_attribute; sai_bulk_object_get_attribute_fn get_next_hop_group_members_attribute; + sai_bulk_object_create_fn create_next_hop_groups; + sai_bulk_object_remove_fn remove_next_hop_groups; + sai_bulk_object_set_attribute_fn set_next_hop_groups_attribute; + sai_bulk_object_get_attribute_fn get_next_hop_groups_attribute; + } sai_next_hop_group_api_t; /**