From 2d2b88edcb3af04428943fb615fe8e8fb2bf5a4b Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Mon, 25 Jan 2021 17:36:40 -0800 Subject: [PATCH 01/13] Add recycle port HLD. --- doc/voq/recycle_port.md | 77 +++++++++++++++++++++++ images/recycle_port_hld/recycle_port.png | Bin 0 -> 16635 bytes 2 files changed, 77 insertions(+) create mode 100644 doc/voq/recycle_port.md create mode 100644 images/recycle_port_hld/recycle_port.png diff --git a/doc/voq/recycle_port.md b/doc/voq/recycle_port.md new file mode 100644 index 0000000000..51eca0e61b --- /dev/null +++ b/doc/voq/recycle_port.md @@ -0,0 +1,77 @@ +# Recycle port support on VOQ chassis + +# High Level Design Document +#### Rev 1 + +# Table of Contents +* [List of Tables](#list-of-tables) +* [List of Figures](#list-of-figures) +* [Revision](#revision) +* [About this Manual](#about-this-manual) +* [Scope](#scope) +* [Definitions/Abbreviations](#definitionsabbreviations) +* [1 Design](#1-design) + +# List of Tables +* [Table 1: Abbreviations](#definitionsabbreviations) + +# List of Figures + +# Revision +| Rev | Date | Author | Change Description | +|:---:|:-----------:|:------------------:|--------------------| +| 1 | Dec-24 2021 | Song Yuan, Eswaran Baskaran (Arista Networks) | Initial Version | + +# About this manual + +This document provides an overview of the SONiC support for recycle ports in a VOQ-based chassis. In a VOQ-based chassis, the packet received by one chip (i.e., the ingress chip) can be forwarded out of another chip (i.e., the egress chip). This inter-chip forwarding generally requires co-ordinating the programming of the egress chip (with the correct rewrite data) and the ingress chip. The recycle port, a special port for which the egress of the port is looped back to the ingress, makes it possible to achieve the inter-chip forwarding without co-ordinating the programming of the egress chip along with the ingress chip. + +# Scope + +The goal of this document is to describe the design of SONIC support for recycle ports in a VOQ-based chassis. + +# Definitions/Abbreviations + +| | | | +|------|--------------------|--------------------------------| +| ASIC | Application Specific Integrated Circuit | Refers to the forwarding engine on a device that is responsible for packet forwarding. | + + +# 1 Design +A packet sent to a recycle port is looped back to the ingress pipeline of the ASIC where the recycle port belongs to. Once the packet comes back to the ingress pipeline again, it will be forwarded to the egress ASIC where the packet gets switched out of the destination port. + +The figure below shows an example of the forwarding path via recycle port. + +![](../../images/recycle_port_hld/recycle_port.png) + +The packet sent to the recycle port can either originate from the network, e.g., as shown in the above figure, or received from a local kernel interface. The packet sent to a recycle port needs to be correctly crafted or rewritten, e.g., having the correct DMAC or destination IP. Otherwise, it won’t be forwarded correctly when it comes into the ingress pipeline again. + +## 1.1 Recycle-to-bridged vs. Recycle-to-routed + +Depending on the DMAC of the recycled packet and the configuration of the recycle port, the packet coming out from recycle port can either bridged (i.e., recycle-to-bridged) or routed (i.e., recycle-to-routed) in the ingress ASIC. If the DMAC is not the router MAC of the ingress ASIC, the packet is bridged according to its DMAC. If the DMAC is router MAC and the recycle port is configured as a routed port, the packet will be routed based on the destination IP of the rewritten packet. + +To ensure the recycled packet is bridged/routed correctly, the corresponding FDB or route entry must be programmed in the ingress ASIC. + +In general, recycle-to-routed is more preferred to reccyle-to-bridged because the former can take the advantages of L3 forwarding features like ECMP. However, recycle-to-routed is also having its own limitation/issue. For example, the TTL of the egress packet may be decremented twice because the packet is routed twice. + +## 1.2 Explict recycle ports + +Since the traffic is forwarded via recycle ports, it’s ideal to have statistics, like counters or errors, collected for recycle ports as well just like for front panel ports. This makes it easier to debug forwarding issue in which recycle ports are involved. To this end recycle ports need to be made visible to SONiC. + +The support of explicit recycle ports requires the minimal changes to SAI as long as recycle ports can be created. SONiC discovers the recycle ports just like front panel ports and explicitly passes the recycle ports (precisely their SAI port Ids) in SAI calls if needed. + +## 1.3 Configuration of recycle ports + +Recycle ports are configured in port_config.ini just like front panel ports. In order to distinguish recycle from front panel ports, the appropriate port role must be set for recycle ports. The port role must indicate the intended use of a recycle port. SONiC can discover all configured recycle ports, based on their port roles, and use them appropriately. + +Two recycle ports, Recirc0 and Recirc1, are configured in the example port_config.ini below. The port role is Rec, which means Recirc0 and Recirc1 will recycle packet to be routed. + +name lanes alias index role speed +Ethernet0 48,49,50,51,52,53,54,55 Ethernet1/1 1 Ext 400000 +Ethernet8 56,57,58,59,60,61,62,63 Ethernet2/1 2 Ext 400000 +Ethernet16 64,65,66,67,68,69,70,71 Ethernet3/1 3 Ext 400000 +Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400000 +Recirc0 221 Recirc0/0 5 Rec 400000 +Recirc1 222 Recirc0/1 6 Rec 400000 + +The lanes of recycle ports must be provided in port_config.ini as well. This allows SONiC to discover the corresponding SAI ports for the configured recycle ports. diff --git a/images/recycle_port_hld/recycle_port.png b/images/recycle_port_hld/recycle_port.png new file mode 100644 index 0000000000000000000000000000000000000000..8634713247799bff16d3717dd5072139a50b04fe GIT binary patch literal 16635 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

_SJdkl1wm>&{+3nx7|h%>~nYg?a7n^ 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 Date: Mon, 25 Jan 2021 20:01:29 -0800 Subject: [PATCH 02/13] Update recycle port figure. --- images/recycle_port_hld/recycle_port.png | Bin 16635 -> 23991 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/images/recycle_port_hld/recycle_port.png b/images/recycle_port_hld/recycle_port.png index 8634713247799bff16d3717dd5072139a50b04fe..c49e430d347b622937a9b8ad0a0c66e58b4b13a0 100644 GIT binary patch literal 23991 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 literal 16635 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

_SJdkl1wm>&{+3nx7|h%>~nYg?a7n^ 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 Date: Mon, 25 Jan 2021 20:06:28 -0800 Subject: [PATCH 03/13] Update example port_config. --- doc/voq/recycle_port.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/voq/recycle_port.md b/doc/voq/recycle_port.md index 51eca0e61b..a412aaf499 100644 --- a/doc/voq/recycle_port.md +++ b/doc/voq/recycle_port.md @@ -65,13 +65,15 @@ The support of explicit recycle ports requires the minimal changes to SAI as lon Recycle ports are configured in port_config.ini just like front panel ports. In order to distinguish recycle from front panel ports, the appropriate port role must be set for recycle ports. The port role must indicate the intended use of a recycle port. SONiC can discover all configured recycle ports, based on their port roles, and use them appropriately. Two recycle ports, Recirc0 and Recirc1, are configured in the example port_config.ini below. The port role is Rec, which means Recirc0 and Recirc1 will recycle packet to be routed. - -name lanes alias index role speed + +``` +#name lanes alias index role speed Ethernet0 48,49,50,51,52,53,54,55 Ethernet1/1 1 Ext 400000 Ethernet8 56,57,58,59,60,61,62,63 Ethernet2/1 2 Ext 400000 Ethernet16 64,65,66,67,68,69,70,71 Ethernet3/1 3 Ext 400000 Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400000 Recirc0 221 Recirc0/0 5 Rec 400000 Recirc1 222 Recirc0/1 6 Rec 400000 +``` The lanes of recycle ports must be provided in port_config.ini as well. This allows SONiC to discover the corresponding SAI ports for the configured recycle ports. From 018866a2e9726e0e6d63c33021220f8b5cb37798 Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Mon, 25 Jan 2021 20:15:41 -0800 Subject: [PATCH 04/13] Fix date --- doc/voq/recycle_port.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/voq/recycle_port.md b/doc/voq/recycle_port.md index a412aaf499..da8e6c342e 100644 --- a/doc/voq/recycle_port.md +++ b/doc/voq/recycle_port.md @@ -20,7 +20,7 @@ # Revision | Rev | Date | Author | Change Description | |:---:|:-----------:|:------------------:|--------------------| -| 1 | Dec-24 2021 | Song Yuan, Eswaran Baskaran (Arista Networks) | Initial Version | +| 1 | Jan-25 2021 | Song Yuan, Eswaran Baskaran (Arista Networks) | Initial Version | # About this manual From dade687ce11b1be5a0f549d116ff1450c2175582 Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Wed, 27 Jan 2021 10:26:26 -0800 Subject: [PATCH 05/13] Address comments in HLD review. --- doc/voq/recycle_port.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/voq/recycle_port.md b/doc/voq/recycle_port.md index da8e6c342e..6fccf9402d 100644 --- a/doc/voq/recycle_port.md +++ b/doc/voq/recycle_port.md @@ -64,16 +64,16 @@ The support of explicit recycle ports requires the minimal changes to SAI as lon Recycle ports are configured in port_config.ini just like front panel ports. In order to distinguish recycle from front panel ports, the appropriate port role must be set for recycle ports. The port role must indicate the intended use of a recycle port. SONiC can discover all configured recycle ports, based on their port roles, and use them appropriately. -Two recycle ports, Recirc0 and Recirc1, are configured in the example port_config.ini below. The port role is Rec, which means Recirc0 and Recirc1 will recycle packet to be routed. +Two recycle ports, Ethernet-Recirc0 and Ethernet-Recirc1, are configured in the example port_config.ini below. Ethernet-Recirc0 is used to recycle packet to be routed, which has port role Rec. Ethernet-Recirc1 is used as inband port and thus its port role is set to Inb. ``` -#name lanes alias index role speed -Ethernet0 48,49,50,51,52,53,54,55 Ethernet1/1 1 Ext 400000 -Ethernet8 56,57,58,59,60,61,62,63 Ethernet2/1 2 Ext 400000 -Ethernet16 64,65,66,67,68,69,70,71 Ethernet3/1 3 Ext 400000 -Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400000 -Recirc0 221 Recirc0/0 5 Rec 400000 -Recirc1 222 Recirc0/1 6 Rec 400000 +#name lanes alias index role speed +Ethernet0 48,49,50,51,52,53,54,55 Ethernet1/1 1 Ext 400000 +Ethernet8 56,57,58,59,60,61,62,63 Ethernet2/1 2 Ext 400000 +Ethernet16 64,65,66,67,68,69,70,71 Ethernet3/1 3 Ext 400000 +Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400000 +Ethernet-Recirc0 221 Recirc0/0 5 Rec 400000 +Ethernet-Recirc1 222 Recirc0/1 6 Inb 400000 ``` The lanes of recycle ports must be provided in port_config.ini as well. This allows SONiC to discover the corresponding SAI ports for the configured recycle ports. From a6d312c28acd3c7f5837a85b042e0f1684e86b4e Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Sat, 30 Jan 2021 20:42:11 -0800 Subject: [PATCH 06/13] Update reccyle port name. --- doc/voq/recycle_port.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/voq/recycle_port.md b/doc/voq/recycle_port.md index 6fccf9402d..3f421532c2 100644 --- a/doc/voq/recycle_port.md +++ b/doc/voq/recycle_port.md @@ -64,16 +64,16 @@ The support of explicit recycle ports requires the minimal changes to SAI as lon Recycle ports are configured in port_config.ini just like front panel ports. In order to distinguish recycle from front panel ports, the appropriate port role must be set for recycle ports. The port role must indicate the intended use of a recycle port. SONiC can discover all configured recycle ports, based on their port roles, and use them appropriately. -Two recycle ports, Ethernet-Recirc0 and Ethernet-Recirc1, are configured in the example port_config.ini below. Ethernet-Recirc0 is used to recycle packet to be routed, which has port role Rec. Ethernet-Recirc1 is used as inband port and thus its port role is set to Inb. +Two recycle ports, Ethernet-Rec0 and Ethernet-Rec1, are configured in the example port_config.ini below. Ethernet-Rec0 is used to recycle packet to be routed, which has port role Rec. Ethernet-Rec1 is used as inband port and thus its port role is set to Inb. ``` -#name lanes alias index role speed -Ethernet0 48,49,50,51,52,53,54,55 Ethernet1/1 1 Ext 400000 -Ethernet8 56,57,58,59,60,61,62,63 Ethernet2/1 2 Ext 400000 -Ethernet16 64,65,66,67,68,69,70,71 Ethernet3/1 3 Ext 400000 -Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400000 -Ethernet-Recirc0 221 Recirc0/0 5 Rec 400000 -Ethernet-Recirc1 222 Recirc0/1 6 Inb 400000 +#name lanes alias index role speed +Ethernet0 48,49,50,51,52,53,54,55 Ethernet1/1 1 Ext 400000 +Ethernet8 56,57,58,59,60,61,62,63 Ethernet2/1 2 Ext 400000 +Ethernet16 64,65,66,67,68,69,70,71 Ethernet3/1 3 Ext 400000 +Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400000 +Ethernet-Rec0 221 Recirc0/0 5 Rec 400000 +Ethernet-Rec1 222 Recirc0/1 6 Inb 400000 ``` The lanes of recycle ports must be provided in port_config.ini as well. This allows SONiC to discover the corresponding SAI ports for the configured recycle ports. From 8694771dac10faf54a3b324c7dc7c4f45fac9bf4 Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Sat, 30 Jan 2021 21:25:28 -0800 Subject: [PATCH 07/13] Update HLD. --- doc/voq/recycle_port.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/voq/recycle_port.md b/doc/voq/recycle_port.md index 3f421532c2..28b52b9f4a 100644 --- a/doc/voq/recycle_port.md +++ b/doc/voq/recycle_port.md @@ -64,7 +64,9 @@ The support of explicit recycle ports requires the minimal changes to SAI as lon Recycle ports are configured in port_config.ini just like front panel ports. In order to distinguish recycle from front panel ports, the appropriate port role must be set for recycle ports. The port role must indicate the intended use of a recycle port. SONiC can discover all configured recycle ports, based on their port roles, and use them appropriately. -Two recycle ports, Ethernet-Rec0 and Ethernet-Rec1, are configured in the example port_config.ini below. Ethernet-Rec0 is used to recycle packet to be routed, which has port role Rec. Ethernet-Rec1 is used as inband port and thus its port role is set to Inb. +As of now, there are two use cases of recycle ports: inband port[here](https://github.com/Azure/SONiC/blob/master/doc/voq/architecture.md), or features like Everflow that needs to recycle encapsulated packets to be routed to the egress ASIC[here](https://github.com/Azure/SONiC/pull/716/files). In order to ensure the right recycle ports are used, we introduce two port roles, Inb and Rec, for the two use cases respectively. + +Two recycle ports, Ethernet-Rec0 and Ethernet-Rec1, are configured in the example port_config.ini below. Ethernet-Rec0 is used by Everflow, which has port role Rec. Ethernet-Rec1 is used as an inband port and thus its port role is set to Inb. The recycle port's lanes, used to discover the corresponding SAI ports, must be provided in port_config.ini as well. ``` #name lanes alias index role speed @@ -76,4 +78,4 @@ Ethernet-Rec0 221 Recirc0/0 5 Rec 400 Ethernet-Rec1 222 Recirc0/1 6 Inb 400000 ``` -The lanes of recycle ports must be provided in port_config.ini as well. This allows SONiC to discover the corresponding SAI ports for the configured recycle ports. +The process of recycle ports in SWSS container is similar to front panel ports: portsyncd populates recycle ports into APPL_DB PORT_TABLE; portsorch discovers, initializes recycle ports, and adds host interfaces for them; and intfsorch adds router interfaces for recycle ports. From a88e875a8204cfb836cd73811cf2883a55e01f73 Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Sat, 30 Jan 2021 21:30:01 -0800 Subject: [PATCH 08/13] Update HLD. --- doc/voq/recycle_port.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/voq/recycle_port.md b/doc/voq/recycle_port.md index 28b52b9f4a..8ab4fa6bdc 100644 --- a/doc/voq/recycle_port.md +++ b/doc/voq/recycle_port.md @@ -64,7 +64,7 @@ The support of explicit recycle ports requires the minimal changes to SAI as lon Recycle ports are configured in port_config.ini just like front panel ports. In order to distinguish recycle from front panel ports, the appropriate port role must be set for recycle ports. The port role must indicate the intended use of a recycle port. SONiC can discover all configured recycle ports, based on their port roles, and use them appropriately. -As of now, there are two use cases of recycle ports: inband port[here](https://github.com/Azure/SONiC/blob/master/doc/voq/architecture.md), or features like Everflow that needs to recycle encapsulated packets to be routed to the egress ASIC[here](https://github.com/Azure/SONiC/pull/716/files). In order to ensure the right recycle ports are used, we introduce two port roles, Inb and Rec, for the two use cases respectively. +As of now, there are two use cases of recycle ports: inband port [here](https://github.com/Azure/SONiC/blob/master/doc/voq/architecture.md), or features like Everflow that needs to recycle encapsulated packets to be routed to the egress ASIC [here](https://github.com/Azure/SONiC/pull/716/files). In order to ensure the right recycle ports are used, we introduce two port roles, Inb and Rec, for the two use cases respectively. Two recycle ports, Ethernet-Rec0 and Ethernet-Rec1, are configured in the example port_config.ini below. Ethernet-Rec0 is used by Everflow, which has port role Rec. Ethernet-Rec1 is used as an inband port and thus its port role is set to Inb. The recycle port's lanes, used to discover the corresponding SAI ports, must be provided in port_config.ini as well. From eaffd39b1a7887230b8e5f7213c1e12650d07537 Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Tue, 9 Mar 2021 13:10:13 -0800 Subject: [PATCH 09/13] Rename inband port Ethernet-Rec1 to Ethernet-IB0. --- doc/voq/recycle_port.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/voq/recycle_port.md b/doc/voq/recycle_port.md index 8ab4fa6bdc..34c9e47e58 100644 --- a/doc/voq/recycle_port.md +++ b/doc/voq/recycle_port.md @@ -66,7 +66,7 @@ Recycle ports are configured in port_config.ini just like front panel ports. In As of now, there are two use cases of recycle ports: inband port [here](https://github.com/Azure/SONiC/blob/master/doc/voq/architecture.md), or features like Everflow that needs to recycle encapsulated packets to be routed to the egress ASIC [here](https://github.com/Azure/SONiC/pull/716/files). In order to ensure the right recycle ports are used, we introduce two port roles, Inb and Rec, for the two use cases respectively. -Two recycle ports, Ethernet-Rec0 and Ethernet-Rec1, are configured in the example port_config.ini below. Ethernet-Rec0 is used by Everflow, which has port role Rec. Ethernet-Rec1 is used as an inband port and thus its port role is set to Inb. The recycle port's lanes, used to discover the corresponding SAI ports, must be provided in port_config.ini as well. +Two recycle ports, Ethernet-Rec0 and Ethernet-IB0, are configured in the example port_config.ini below. Ethernet-Rec0 is used by Everflow, which has port role Rec. Ethernet-IB0 is used as an inband port and thus its port role is set to Inb. The recycle port's lanes, used to discover the corresponding SAI ports, must be provided in port_config.ini as well. ``` #name lanes alias index role speed @@ -75,7 +75,7 @@ Ethernet8 56,57,58,59,60,61,62,63 Ethernet2/1 2 Ext 400 Ethernet16 64,65,66,67,68,69,70,71 Ethernet3/1 3 Ext 400000 Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400000 Ethernet-Rec0 221 Recirc0/0 5 Rec 400000 -Ethernet-Rec1 222 Recirc0/1 6 Inb 400000 +Ethernet-IB0 222 Recirc0/1 6 Inb 400000 ``` The process of recycle ports in SWSS container is similar to front panel ports: portsyncd populates recycle ports into APPL_DB PORT_TABLE; portsorch discovers, initializes recycle ports, and adds host interfaces for them; and intfsorch adds router interfaces for recycle ports. From ad646bc7a7f671d72852381e5fc3398884773be2 Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Wed, 5 May 2021 16:49:19 -0700 Subject: [PATCH 10/13] Address review comments --- doc/recirculation-port/recirculation_port.hld | 91 ++++++++++++++++++ .../recirculation-port/recirculation_port.png | Bin doc/voq/recycle_port.md | 81 ---------------- 3 files changed, 91 insertions(+), 81 deletions(-) create mode 100644 doc/recirculation-port/recirculation_port.hld rename images/recycle_port_hld/recycle_port.png => doc/recirculation-port/recirculation_port.png (100%) delete mode 100644 doc/voq/recycle_port.md diff --git a/doc/recirculation-port/recirculation_port.hld b/doc/recirculation-port/recirculation_port.hld new file mode 100644 index 0000000000..11089de8f2 --- /dev/null +++ b/doc/recirculation-port/recirculation_port.hld @@ -0,0 +1,91 @@ +# Recirculation port support on VOQ chassis + +# High Level Design Document +#### Rev 1 + +# Table of Contents +* [List of Tables](#list-of-tables) +* [List of Figures](#list-of-figures) +* [Revision](#revision) +* [About this Manual](#about-this-manual) +* [Scope](#scope) +* [Definitions/Abbreviations](#definitionsabbreviations) +* [1 Design](#1-design) + +# List of Tables +* [Table 1: Abbreviations](#definitionsabbreviations) + +# List of Figures + +# Revision +| Rev | Date | Author | Change Description | +|:---:|:-----------:|:------------------:|--------------------| +| 1 | Jan-25 2021 | Song Yuan, Eswaran Baskaran (Arista Networks) | Initial Version | + +# About this manual + +This document provides an overview of the SONiC support for recirculation ports in a VOQ-based chassis. In a VOQ-based chassis, the packet received by one chip (i.e., the ingress chip) can be forwarded out of another chip (i.e., the egress chip). This inter-chip forwarding generally requires co-ordinating the programming of the egress chip (with the correct rewrite data) and the ingress chip. The recirculation port, a special port for which the egress of the port is looped back to the ingress, makes it possible to achieve the inter-chip forwarding without co-ordinating the programming of the egress chip along with the ingress chip. Throughout the document, we will use the terms: recirculation and recycle interchangeably. + +# Scope + +The goal of this document is to describe the design of SONIC support for recirculation ports in a VOQ-based chassis. + +# Definitions/Abbreviations + +| | | | +|------|--------------------|--------------------------------| +| ASIC | Application Specific Integrated Circuit | Refers to the forwarding engine on a device that is responsible for packet forwarding. | + + +# 1 Design +A packet sent to a recirculation port is looped back to the ingress pipeline of the ASIC where the recirculation port belongs to. Once the packet comes back to the ingress pipeline again, it will be forwarded to the egress ASIC where the packet gets switched out of the destination port. + +The figure below shows an example of the forwarding path via recirculation port. + +![](recirculation_port.png) + +The packet sent to the recirculation port can either originate from the network, e.g., as shown in the above figure, or received from a local kernel interface. The packet sent to a recirculation port needs to be correctly crafted or rewritten, e.g., having the correct DMAC or destination IP. Otherwise, it won’t be forwarded correctly when it comes into the ingress pipeline again. + +## 1.1 Recycle-to-bridged vs. Recycle-to-routed + +Depending on the DMAC of the recycled packet and the configuration of the recycle port, the packet coming out from recycle port can either bridged (i.e., recycle-to-bridged) or routed (i.e., recycle-to-routed) in the ingress ASIC. If the DMAC is not the router MAC of the ingress ASIC, the packet is bridged according to its DMAC. If the DMAC is router MAC and the recycle port is configured as a routed port, the packet will be routed based on the destination IP of the rewritten packet. + +To ensure the recycled packet is bridged/routed correctly, the corresponding FDB or route entry must be programmed in the ingress ASIC. + +In general, recycle-to-routed is more preferred to reccyle-to-bridged because the former can take the advantages of L3 forwarding features like ECMP. However, recycle-to-routed is also having its own limitation/issue. For example, the TTL of the egress packet may be decremented twice because the packet is routed twice. + +## 1.2 Explict recycle ports + +Since the traffic is forwarded via recycle ports, it’s ideal to have statistics, like counters or errors, collected for recycle ports as well just like for front panel ports. This makes it easier to debug forwarding issue in which recycle ports are involved. To this end recycle ports need to be made visible to SONiC. + +The support of explicit recycle ports requires the minimal changes to SAI as long as recycle ports can be created. SONiC discovers the recycle ports just like front panel ports and explicitly passes the recycle ports (precisely their SAI port Ids) in SAI calls if needed. + +## 1.3 Configuration of recirculation ports + +Recirculation ports are configured in port_config.ini just like front panel ports. In order to distinguish recirculation from front panel ports, the appropriate port role must be set for recirculation ports. The port role must indicate the intended use of a recirculation port. SONiC can discover all configured recirculation ports, based on their port roles, and use them appropriately. + +As of now, there are two use cases of recirculation ports: inband port [here](https://github.com/Azure/SONiC/blob/master/doc/voq/architecture.md), or features like Everflow that needs to recycle encapsulated packets to be routed to the egress ASIC [here](https://github.com/Azure/SONiC/pull/716/files). In order to ensure the right recirculation ports are used, we introduce two port roles, Inb and Rec, for the two use cases respectively. + +Two recirculation ports, Ethernet-Rec0 and Ethernet-IB0, are configured in the example port_config.ini below. Ethernet-Rec0 is used by Everflow, which has port role Rec. Ethernet-IB0 is used as an inband port and thus its port role is set to Inb. The recirculation port's lanes, used to discover the corresponding SAI ports, must be provided in port_config.ini as well. + +``` +#name lanes alias index role speed +Ethernet0 48,49,50,51,52,53,54,55 Ethernet1/1 1 Ext 400000 +Ethernet8 56,57,58,59,60,61,62,63 Ethernet2/1 2 Ext 400000 +Ethernet16 64,65,66,67,68,69,70,71 Ethernet3/1 3 Ext 400000 +Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400000 +Ethernet-Rec0 221 Recirc0/0 5 Rec 400000 +Ethernet-IB0 222 Recirc0/1 6 Inb 400000 +``` +The following is the example output of the above ports from "show interfaces status" CLI command: + + Interface Lanes Speed MTU FEC Alias Vlan Oper Admin Type Asym PFC +----------- ----------------------- ------- ----- ----- ------------ ------ ------ ------- ----------------------------- ---------- + Ethernet0 48,49,50,51,52,53,54,55 400G 9100 none Ethernet1/1 routed up up OSFP 8X Pluggable Transceiver off + Ethernet8 56,57,58,59,60,61,62,63 400G 9100 none Ethernet2/1 routed up up OSFP 8X Pluggable Transceiver off + Ethernet16 64,65,66,67,68,69,70,71 400G 9100 none Ethernet3/1 routed up up OSFP 8X Pluggable Transceiver off + Ethernet24 72,73,74,75,76,77,78,79 400G 9100 none Ethernet4/1 routed up up OSFP 8X Pluggable Transceiver off + Ethernet-Rec0 221 400G 9100 N/A Recirc0/0 routed up up N/A off + Ethernet-IB0 222 400G 9100 N/A Recirc0/1 routed up up N/A off + +The process of recirculation ports in SWSS container is similar to front panel ports: portsyncd populates recirculation ports into APPL_DB PORT_TABLE; portsorch discovers, initializes recirculation ports, and adds host interfaces for them; and intfsorch adds router interfaces for recirculation ports. diff --git a/images/recycle_port_hld/recycle_port.png b/doc/recirculation-port/recirculation_port.png similarity index 100% rename from images/recycle_port_hld/recycle_port.png rename to doc/recirculation-port/recirculation_port.png diff --git a/doc/voq/recycle_port.md b/doc/voq/recycle_port.md deleted file mode 100644 index 34c9e47e58..0000000000 --- a/doc/voq/recycle_port.md +++ /dev/null @@ -1,81 +0,0 @@ -# Recycle port support on VOQ chassis - -# High Level Design Document -#### Rev 1 - -# Table of Contents -* [List of Tables](#list-of-tables) -* [List of Figures](#list-of-figures) -* [Revision](#revision) -* [About this Manual](#about-this-manual) -* [Scope](#scope) -* [Definitions/Abbreviations](#definitionsabbreviations) -* [1 Design](#1-design) - -# List of Tables -* [Table 1: Abbreviations](#definitionsabbreviations) - -# List of Figures - -# Revision -| Rev | Date | Author | Change Description | -|:---:|:-----------:|:------------------:|--------------------| -| 1 | Jan-25 2021 | Song Yuan, Eswaran Baskaran (Arista Networks) | Initial Version | - -# About this manual - -This document provides an overview of the SONiC support for recycle ports in a VOQ-based chassis. In a VOQ-based chassis, the packet received by one chip (i.e., the ingress chip) can be forwarded out of another chip (i.e., the egress chip). This inter-chip forwarding generally requires co-ordinating the programming of the egress chip (with the correct rewrite data) and the ingress chip. The recycle port, a special port for which the egress of the port is looped back to the ingress, makes it possible to achieve the inter-chip forwarding without co-ordinating the programming of the egress chip along with the ingress chip. - -# Scope - -The goal of this document is to describe the design of SONIC support for recycle ports in a VOQ-based chassis. - -# Definitions/Abbreviations - -| | | | -|------|--------------------|--------------------------------| -| ASIC | Application Specific Integrated Circuit | Refers to the forwarding engine on a device that is responsible for packet forwarding. | - - -# 1 Design -A packet sent to a recycle port is looped back to the ingress pipeline of the ASIC where the recycle port belongs to. Once the packet comes back to the ingress pipeline again, it will be forwarded to the egress ASIC where the packet gets switched out of the destination port. - -The figure below shows an example of the forwarding path via recycle port. - -![](../../images/recycle_port_hld/recycle_port.png) - -The packet sent to the recycle port can either originate from the network, e.g., as shown in the above figure, or received from a local kernel interface. The packet sent to a recycle port needs to be correctly crafted or rewritten, e.g., having the correct DMAC or destination IP. Otherwise, it won’t be forwarded correctly when it comes into the ingress pipeline again. - -## 1.1 Recycle-to-bridged vs. Recycle-to-routed - -Depending on the DMAC of the recycled packet and the configuration of the recycle port, the packet coming out from recycle port can either bridged (i.e., recycle-to-bridged) or routed (i.e., recycle-to-routed) in the ingress ASIC. If the DMAC is not the router MAC of the ingress ASIC, the packet is bridged according to its DMAC. If the DMAC is router MAC and the recycle port is configured as a routed port, the packet will be routed based on the destination IP of the rewritten packet. - -To ensure the recycled packet is bridged/routed correctly, the corresponding FDB or route entry must be programmed in the ingress ASIC. - -In general, recycle-to-routed is more preferred to reccyle-to-bridged because the former can take the advantages of L3 forwarding features like ECMP. However, recycle-to-routed is also having its own limitation/issue. For example, the TTL of the egress packet may be decremented twice because the packet is routed twice. - -## 1.2 Explict recycle ports - -Since the traffic is forwarded via recycle ports, it’s ideal to have statistics, like counters or errors, collected for recycle ports as well just like for front panel ports. This makes it easier to debug forwarding issue in which recycle ports are involved. To this end recycle ports need to be made visible to SONiC. - -The support of explicit recycle ports requires the minimal changes to SAI as long as recycle ports can be created. SONiC discovers the recycle ports just like front panel ports and explicitly passes the recycle ports (precisely their SAI port Ids) in SAI calls if needed. - -## 1.3 Configuration of recycle ports - -Recycle ports are configured in port_config.ini just like front panel ports. In order to distinguish recycle from front panel ports, the appropriate port role must be set for recycle ports. The port role must indicate the intended use of a recycle port. SONiC can discover all configured recycle ports, based on their port roles, and use them appropriately. - -As of now, there are two use cases of recycle ports: inband port [here](https://github.com/Azure/SONiC/blob/master/doc/voq/architecture.md), or features like Everflow that needs to recycle encapsulated packets to be routed to the egress ASIC [here](https://github.com/Azure/SONiC/pull/716/files). In order to ensure the right recycle ports are used, we introduce two port roles, Inb and Rec, for the two use cases respectively. - -Two recycle ports, Ethernet-Rec0 and Ethernet-IB0, are configured in the example port_config.ini below. Ethernet-Rec0 is used by Everflow, which has port role Rec. Ethernet-IB0 is used as an inband port and thus its port role is set to Inb. The recycle port's lanes, used to discover the corresponding SAI ports, must be provided in port_config.ini as well. - -``` -#name lanes alias index role speed -Ethernet0 48,49,50,51,52,53,54,55 Ethernet1/1 1 Ext 400000 -Ethernet8 56,57,58,59,60,61,62,63 Ethernet2/1 2 Ext 400000 -Ethernet16 64,65,66,67,68,69,70,71 Ethernet3/1 3 Ext 400000 -Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400000 -Ethernet-Rec0 221 Recirc0/0 5 Rec 400000 -Ethernet-IB0 222 Recirc0/1 6 Inb 400000 -``` - -The process of recycle ports in SWSS container is similar to front panel ports: portsyncd populates recycle ports into APPL_DB PORT_TABLE; portsorch discovers, initializes recycle ports, and adds host interfaces for them; and intfsorch adds router interfaces for recycle ports. From 8f8f353f444980aeb028e2cfc01eeed8f9eddb9c Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Wed, 5 May 2021 16:53:27 -0700 Subject: [PATCH 11/13] Fix typo --- .../{recirculation_port.hld => recirculation_port.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/recirculation-port/{recirculation_port.hld => recirculation_port.md} (100%) diff --git a/doc/recirculation-port/recirculation_port.hld b/doc/recirculation-port/recirculation_port.md similarity index 100% rename from doc/recirculation-port/recirculation_port.hld rename to doc/recirculation-port/recirculation_port.md From ed5638517d3cb1833e816edf002d282b6576f3a7 Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Wed, 5 May 2021 17:08:14 -0700 Subject: [PATCH 12/13] Add a seciont for SAI --- doc/recirculation-port/recirculation_port.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/recirculation-port/recirculation_port.md b/doc/recirculation-port/recirculation_port.md index 11089de8f2..441489c2d1 100644 --- a/doc/recirculation-port/recirculation_port.md +++ b/doc/recirculation-port/recirculation_port.md @@ -79,6 +79,7 @@ Ethernet-IB0 222 Recirc0/1 6 Inb 400 ``` The following is the example output of the above ports from "show interfaces status" CLI command: +``` Interface Lanes Speed MTU FEC Alias Vlan Oper Admin Type Asym PFC ----------- ----------------------- ------- ----- ----- ------------ ------ ------ ------- ----------------------------- ---------- Ethernet0 48,49,50,51,52,53,54,55 400G 9100 none Ethernet1/1 routed up up OSFP 8X Pluggable Transceiver off @@ -87,5 +88,9 @@ The following is the example output of the above ports from "show interfaces sta Ethernet24 72,73,74,75,76,77,78,79 400G 9100 none Ethernet4/1 routed up up OSFP 8X Pluggable Transceiver off Ethernet-Rec0 221 400G 9100 N/A Recirc0/0 routed up up N/A off Ethernet-IB0 222 400G 9100 N/A Recirc0/1 routed up up N/A off - +``` The process of recirculation ports in SWSS container is similar to front panel ports: portsyncd populates recirculation ports into APPL_DB PORT_TABLE; portsorch discovers, initializes recirculation ports, and adds host interfaces for them; and intfsorch adds router interfaces for recirculation ports. + +## 1.4 SAI + +ASIC vendoers may implement recirculation ports in different ways. If recirculation ports are implemented just like front panel ports, then no SAI change is required because recirculation ports can be initialized and configured by using existing SAI port API. \ No newline at end of file From 1066f941d58ca4171944df088acab076efcc1447 Mon Sep 17 00:00:00 2001 From: Song Yuan Date: Mon, 10 May 2021 10:52:46 -0700 Subject: [PATCH 13/13] Add config example in platform.json --- doc/recirculation-port/recirculation_port.md | 22 +++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/doc/recirculation-port/recirculation_port.md b/doc/recirculation-port/recirculation_port.md index 441489c2d1..26ab8b4205 100644 --- a/doc/recirculation-port/recirculation_port.md +++ b/doc/recirculation-port/recirculation_port.md @@ -62,7 +62,7 @@ The support of explicit recycle ports requires the minimal changes to SAI as lon ## 1.3 Configuration of recirculation ports -Recirculation ports are configured in port_config.ini just like front panel ports. In order to distinguish recirculation from front panel ports, the appropriate port role must be set for recirculation ports. The port role must indicate the intended use of a recirculation port. SONiC can discover all configured recirculation ports, based on their port roles, and use them appropriately. +Recirculation ports are configured in port_config.ini or platform.json just like front panel ports. In order to distinguish recirculation from front panel ports, the appropriate port role must be set for recirculation ports. The port role must indicate the intended use of a recirculation port. SONiC can discover all configured recirculation ports, based on their port roles, and use them appropriately. As of now, there are two use cases of recirculation ports: inband port [here](https://github.com/Azure/SONiC/blob/master/doc/voq/architecture.md), or features like Everflow that needs to recycle encapsulated packets to be routed to the egress ASIC [here](https://github.com/Azure/SONiC/pull/716/files). In order to ensure the right recirculation ports are used, we introduce two port roles, Inb and Rec, for the two use cases respectively. @@ -77,6 +77,26 @@ Ethernet24 72,73,74,75,76,77,78,79 Ethernet4/1 4 Ext 400 Ethernet-Rec0 221 Recirc0/0 5 Rec 400000 Ethernet-IB0 222 Recirc0/1 6 Inb 400000 ``` +Similarly, if recirculation ports are configued in platform.json, their port role must be provided too. For example, the above recirculation ports are defined in platform.json as shown below: +``` + "Ethernet-Rec0": { + "index": "5", + "lanes": "221", + "breakout_modes": { + "1x400G": ["Recirc0/0"] + }, + "role": "Rec" + }, + "Ethernet-IB0": { + "index": "6", + "lanes": "222", + "breakout_modes": { + "1x400G": ["Recirc0/1"] + }, + "role": "Inb" + } +``` + The following is the example output of the above ports from "show interfaces status" CLI command: ```