From 8ea680a21a88b45d25392d210efe61e6dec86054 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Mon, 8 Nov 2021 22:55:53 +0000 Subject: [PATCH 1/5] Order ECMP HLD. Signed-off-by: Abhishek Dosi --- doc/ecmp/ordered_ecmp_next_hop_hld.md | 150 ++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 doc/ecmp/ordered_ecmp_next_hop_hld.md diff --git a/doc/ecmp/ordered_ecmp_next_hop_hld.md b/doc/ecmp/ordered_ecmp_next_hop_hld.md new file mode 100644 index 0000000000..a197cc04cb --- /dev/null +++ b/doc/ecmp/ordered_ecmp_next_hop_hld.md @@ -0,0 +1,150 @@ +# SONiC Ordered ECMP Design +# High Level Design Document +### Rev 0.1 + +# Table of Contents + * [List of Tables](#list-of-tables) + + * [Revision](#revision) + + * [About this Manual](#about-this-manual) + + * [Scope](#scope) + + * [Use case](#use-case) + + * [Definitions/Abbreviation](#definitionsabbreviation) + + * [1 Requirements Overview](#1-requirements-overview) + * [1.1 Use Case](#11-use-case) + * [1.2 Acheiving Order Nexthop member in ECMP](#12-acheiving-order-nexthop-memeber-in-ecmp) + * [1.3 Functional requirements](#13-functional-requirements) + * [2 Modules Design](#2-modules-design) + * [2.1 App DB](#21-app-db) + * [2.2 Orchestration Agent](#24-orchestration-agent) + * [2.3 Backward Compatibility](#25-backward-compatibility) + * [4 Test Plan](#3-test-plan) + +###### Revision +| Rev | Date | Author | Change Description | +|:---:|:-----------:|:------------------:|-----------------------------------| +| 0.1 | 11/05/2021 | Abhishek Dosi | Initial version | + +# About this Manual +This document talks about use-case to support ECMP with Ordered Nexthop and changes needed in SONiC to support same. + +# Definitions/Abbreviation +###### Table 1: Abbreviations +| Abbreviation | Meaning | +|--------------------------|--------------------------------| +| ECMP | Equal Cost MultiPath | + +# 1 Requirements Overview +## 1.1 Use case +Under the ToR (Tier0 device) there can be appliances (eg:Firewall/Software-Load Balancer) which maintain state of flows running through them. For better scaling/high-availaibility/fault-tolerance +set of appliances are used and connected to differnt ToR's. Not all the flow state that are maintained by these appliances in a set are shared between them. Thus with flow state not being sync +if the flow do not end up alawys on to same TOR/Appliance it can cause services (using that flow) degradation and also impact it's availability + +To make sure given flow (identidied by 5 tuple) always end up on to same TOR/Appliance we need ECMP ordered support/feature on T1 (Leaf Router). +With this feature enable even if flow land's on different T1's (which is common to happen as some link/device in the flow path goes/come to/from maintainence) +ECMP memeber being ordered will use same nexthop (T0) and thus same appliace. + +Below diagram captures the use-case (Traffic is flowing from T1 <-> T0 <-> Appliance) + +![](../../images/ecmp/orch_flow.png) + +## 1.2 Acheiving Order Nexthop member in ECMP +1. Nexthop's will be sorted based on their IP address to get thir order within the ECMP group. +In typical data-center ip address allocation scheme all T1’s in a given podset/cluster have the same order for P2P v4/v6 IP Address for all downstream T0's. +2. This feature/enhacement assumes entropy calculation will be same for a given flow on each devices that have set set of nexthop in the ECMP Group. +3. This feature/enhancement is best effort in nature where if the Links/Bgp between pair of devices are not in same state (either Up/Down) then flow can take different path. + +## 1.3 Functional requirements +This section describes the SONiC requirements for Ordered ECMP Nexthop + +At a high level the following should be supported: + +Phase #1 +- Program ECMP memebers (nexthops) in ordered way. Above use case is for ECMP Group on T1 with nexthop memebers as T0 but requirement is generic for any ECMP Group/Tier +- Knob to enable/disable the order ecmp nexthop +- Maintain Backward Compatible if given SAI Vendor can not support ordered ecmp +- Should work with Overlay ECMP. +- Handling linkdown/linkup scenarios which triggers nexthop withdrawal/addition to nexthop group. +- Changes shoud work Nexthop Group OA . + +Phase #2 +- Init time knob to configure key/parameter to use for creating ordered nexthop (default being nexthop ip address) +- Warm restart support (if/when enable on T0) + +# 2 Modules Design + +## 2.1 APP DB +The following are the changes for Switch table +``` +New field "orded_ecmp_group" is added. + +SWITCH_TABLE:switch + "ecmp_hash_seed": {{ecmp_hash_seed}} + .... + "order_ecmp_group": {{bool}} (false being default) + +``` + +## 2.2 Orchestration Agent +Following orchagents shall be modified. +- switchorch +- routeorch +- overlayecmporch +- nexthopgrouporch + +### SwitchOrch + +1. Switch Orch read the APP_DB Switch Table new field "order_ecmp_group" and enable/disable the feature by setting the global flag. +2. The field will be added to switch.json.j2 and will be rendered based on Device role and asic_type. Default value being false. + +### RouteOrch +1. By default, Route OA insert all the Nexthops in sorted order into Nexthop-Group set. Sorting is based nexthop-key tuple with ip address as being the first element. + Thus all the elements in Nexthop Group set are already sorted on IP Address. For Phase#2 init time option will be added to control the key to use for sorting nexthop-group set. + +2. When Route OA create Nexthop-Group and add Nexthop as member to the group following changes will be done:- + - ECMP Group will be created with SAI attribute SAI_NEXT_HOP_GROUP_TYPE_DYNAMIC_ORDERED_ECMP + - When nexthop is added to the group SAI attribute SAI_NEXT_HOP_GROUP_MEMBER_ATTR_SEQUENCE_ID will be used. Passing the sequence id enforces SAI + to program all the members as per application passed order. + - The Sequence Id will be traversal index of nexthop in nexthop group set. We will save this map {nexthop:sequence_id} in the local data structure + +3. When Route OA add/remove member to the Nexthop Group for eg: in case of ECMP HW Acceleration (for link up/down handling) following changes will be done:- + - For remove case no change is needed. SAI should retain the order of all the members still present after the removal of member + - For add case SAI_NEXT_HOP_GROUP_MEMBER_ATTR_SEQUENCE_ID will be used with value being passed from the new map {nexthop:sequence_id} created above. + +4. When Route OA delete Nexthop group member and removes Nexthop-Group no change is needed. Current flow should work. + +### OverlayECMP Orch +Above point discussed for Route OA (w.r.t Single Level Underlay ECMP) applies and will be done for Overlay ECMP Route OA also. +Overlay ECMP Route OA will make sure nexthop will be added into nexthop group set with sorted on the Tunnel Endpoint IP Address. +SAI API changes for Overlay ECMP also will be same as Route OA. + +### NexthopGroup Orch +Nexthop Group OA will be modified similar to Route OA. + +## 2.3 Backward Compatibility +To maintain backward compatibility this feature will only be functionally enabled (even if config wise enable in APP_DB SWITCH_TABLE) +if SAI enum capability query support for SAI_NEXTHOP_GROUP object for attribute SAI_NEXT_HOP_GROUP_ATTR_TYPE return “DYNAMIC_ORDERED_ECMP” as supported. +Otherwise, we will mark the feature as disable (control by global flag) and fall back to existing Unordered ECMP group behavior. + +# 7 Test Plan +The following testing is planned for this feature: +- SWSS unit tests via virtual switch testing +- Data Plane tests via pytest + PTF + +## SWSS unit tests via virtual switch testing +Test details(Applies to all Route/OverlayECMP/NexthopGroup OA): +- Verify ASIC DB has correct sequence id for all nexthops when creating Nexthop Group. +- Verify ASIC DB has correct sequence id for all nexthops when removing Nexthop Group. +- Verify ASIC DB has correct sequence id for nexthop member add/removal from the Group. + +## Data Plane community tests via pytest + PTF +A new Pytest and PTF test will be created for Ordered ECMP testing. The Pytest is responsible for creating/deploying the device configuration, and will invoke PTF test to run the data plane scenario test + +Test details: +- To verify flow is load-balance as per of next-hop sequence for add/remove/add-memeber/remove-memeber case. +- Preserve the test result { flow to nexthop-mapping } so that in case entropy is changed across SONiC/SAI release we can catch/notify about it. From 8ce956605c034e826d1250df37597998499ec323 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Mon, 8 Nov 2021 23:14:36 +0000 Subject: [PATCH 2/5] Added Picture Signed-off-by: Abhishek Dosi --- doc/ecmp/ordered_ecmp_next_hop_hld.md | 2 +- images/ecmp/order_ecmp_pic.png | Bin 0 -> 50598 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 images/ecmp/order_ecmp_pic.png diff --git a/doc/ecmp/ordered_ecmp_next_hop_hld.md b/doc/ecmp/ordered_ecmp_next_hop_hld.md index a197cc04cb..bb2c34049e 100644 --- a/doc/ecmp/ordered_ecmp_next_hop_hld.md +++ b/doc/ecmp/ordered_ecmp_next_hop_hld.md @@ -51,7 +51,7 @@ ECMP memeber being ordered will use same nexthop (T0) and thus same appliace. Below diagram captures the use-case (Traffic is flowing from T1 <-> T0 <-> Appliance) -![](../../images/ecmp/orch_flow.png) +![](../../images/ecmp/order_ecmp_pic.png) ## 1.2 Acheiving Order Nexthop member in ECMP 1. Nexthop's will be sorted based on their IP address to get thir order within the ECMP group. diff --git a/images/ecmp/order_ecmp_pic.png b/images/ecmp/order_ecmp_pic.png new file mode 100644 index 0000000000000000000000000000000000000000..a4166331fb95ff3cc6960e802e4a71bef202bd5d GIT binary patch literal 50598 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 z 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 Date: Mon, 8 Nov 2021 15:20:51 -0800 Subject: [PATCH 3/5] Update ordered_ecmp_next_hop_hld.md --- doc/ecmp/ordered_ecmp_next_hop_hld.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/ecmp/ordered_ecmp_next_hop_hld.md b/doc/ecmp/ordered_ecmp_next_hop_hld.md index bb2c34049e..f592c63496 100644 --- a/doc/ecmp/ordered_ecmp_next_hop_hld.md +++ b/doc/ecmp/ordered_ecmp_next_hop_hld.md @@ -50,11 +50,9 @@ With this feature enable even if flow land's on different T1's (which is common ECMP memeber being ordered will use same nexthop (T0) and thus same appliace. Below diagram captures the use-case (Traffic is flowing from T1 <-> T0 <-> Appliance) - ![](../../images/ecmp/order_ecmp_pic.png) - ## 1.2 Acheiving Order Nexthop member in ECMP -1. Nexthop's will be sorted based on their IP address to get thir order within the ECMP group. +1. Nexthop's will be sorted based on their IP address to get their order within the ECMP group. In typical data-center ip address allocation scheme all T1’s in a given podset/cluster have the same order for P2P v4/v6 IP Address for all downstream T0's. 2. This feature/enhacement assumes entropy calculation will be same for a given flow on each devices that have set set of nexthop in the ECMP Group. 3. This feature/enhancement is best effort in nature where if the Links/Bgp between pair of devices are not in same state (either Up/Down) then flow can take different path. From c7da58313ef216147b16afb16a0d1ab8f2e84d77 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 8 Nov 2021 15:25:23 -0800 Subject: [PATCH 4/5] Update ordered_ecmp_next_hop_hld.md --- doc/ecmp/ordered_ecmp_next_hop_hld.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ecmp/ordered_ecmp_next_hop_hld.md b/doc/ecmp/ordered_ecmp_next_hop_hld.md index f592c63496..ff83286cdf 100644 --- a/doc/ecmp/ordered_ecmp_next_hop_hld.md +++ b/doc/ecmp/ordered_ecmp_next_hop_hld.md @@ -23,7 +23,7 @@ * [2.1 App DB](#21-app-db) * [2.2 Orchestration Agent](#24-orchestration-agent) * [2.3 Backward Compatibility](#25-backward-compatibility) - * [4 Test Plan](#3-test-plan) + * [3 Test Plan](#3-test-plan) ###### Revision | Rev | Date | Author | Change Description | @@ -129,7 +129,7 @@ To maintain backward compatibility this feature will only be functionally enable if SAI enum capability query support for SAI_NEXTHOP_GROUP object for attribute SAI_NEXT_HOP_GROUP_ATTR_TYPE return “DYNAMIC_ORDERED_ECMP” as supported. Otherwise, we will mark the feature as disable (control by global flag) and fall back to existing Unordered ECMP group behavior. -# 7 Test Plan +# 3 Test Plan The following testing is planned for this feature: - SWSS unit tests via virtual switch testing - Data Plane tests via pytest + PTF @@ -144,5 +144,5 @@ Test details(Applies to all Route/OverlayECMP/NexthopGroup OA): A new Pytest and PTF test will be created for Ordered ECMP testing. The Pytest is responsible for creating/deploying the device configuration, and will invoke PTF test to run the data plane scenario test Test details: -- To verify flow is load-balance as per of next-hop sequence for add/remove/add-memeber/remove-memeber case. +- To verify flow is load-balance as per the next-hop sequence in ecmp group for add/remove/add-memeber/remove-memeber case. - Preserve the test result { flow to nexthop-mapping } so that in case entropy is changed across SONiC/SAI release we can catch/notify about it. From bfed708172998f3d03a63fe9f126d6910f1746b9 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Thu, 9 Dec 2021 23:45:07 +0000 Subject: [PATCH 5/5] Address Review Comment Signed-off-by: Abhishek Dosi --- doc/ecmp/ordered_ecmp_next_hop_hld.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/doc/ecmp/ordered_ecmp_next_hop_hld.md b/doc/ecmp/ordered_ecmp_next_hop_hld.md index bb2c34049e..0cec97c7b5 100644 --- a/doc/ecmp/ordered_ecmp_next_hop_hld.md +++ b/doc/ecmp/ordered_ecmp_next_hop_hld.md @@ -29,6 +29,7 @@ | Rev | Date | Author | Change Description | |:---:|:-----------:|:------------------:|-----------------------------------| | 0.1 | 11/05/2021 | Abhishek Dosi | Initial version | +| 0.2 | 12/09/2021 | Abhishek Dosi | Address SONiC Community Feedback | # About this Manual This document talks about use-case to support ECMP with Ordered Nexthop and changes needed in SONiC to support same. @@ -70,11 +71,12 @@ Phase #1 - Maintain Backward Compatible if given SAI Vendor can not support ordered ecmp - Should work with Overlay ECMP. - Handling linkdown/linkup scenarios which triggers nexthop withdrawal/addition to nexthop group. -- Changes shoud work Nexthop Group OA . -Phase #2 +Phase #2 (Not commited as of now) - Init time knob to configure key/parameter to use for creating ordered nexthop (default being nexthop ip address) - Warm restart support (if/when enable on T0) +- Config DB based knob to enable/disable order ecmp feature. This might need system reboot +- Nexthop Group OA # 2 Modules Design @@ -95,7 +97,6 @@ Following orchagents shall be modified. - switchorch - routeorch - overlayecmporch -- nexthopgrouporch ### SwitchOrch @@ -123,9 +124,6 @@ Above point discussed for Route OA (w.r.t Single Level Underlay ECMP) applies an Overlay ECMP Route OA will make sure nexthop will be added into nexthop group set with sorted on the Tunnel Endpoint IP Address. SAI API changes for Overlay ECMP also will be same as Route OA. -### NexthopGroup Orch -Nexthop Group OA will be modified similar to Route OA. - ## 2.3 Backward Compatibility To maintain backward compatibility this feature will only be functionally enabled (even if config wise enable in APP_DB SWITCH_TABLE) if SAI enum capability query support for SAI_NEXTHOP_GROUP object for attribute SAI_NEXT_HOP_GROUP_ATTR_TYPE return “DYNAMIC_ORDERED_ECMP” as supported.