diff --git a/doc/SAI-Proposal-VlanStack-QinQ.md b/doc/SAI-Proposal-VlanStack-QinQ.md new file mode 100644 index 000000000..585d7424a --- /dev/null +++ b/doc/SAI-Proposal-VlanStack-QinQ.md @@ -0,0 +1,435 @@ + +Add support for Vlan Stack +------------------------------------------------------------------------------- + + Title | Vlan Stack +-------------|----------------------------------------------------------------- + Authors | Edge-Core + Status | In review + Type | Standards track + Created | 25/02/2022 + Updated | - + SAI-Version | 1.9.1 + +------------------------------------------------------------------------------- + +## Overview ## + +The Vlan Stack feature includes two functions, vlan translation and QinQ. + +![qinq](figures/vlan_stack/vlan_stack_QinQ_usecase.png "Figure 1: QinQ usage scenario") +__Figure 1: QinQ usage scenario__ + +![vlan_translate](figures/vlan_stack/vlan_stack_vlan_xlate_usecase.png "Figure 2: Vlan translation usage scenario") +__Figure 2: Vlan Translation usage scenario__ + +## Packet Format ## + +Untagged packet, Single tagged packet and Double tagged packet + +![packet_format](figures/vlan_stack/TCPIP_802.1ad_DoubleTag.png "Figure 3: Packet packet format") +__Figure 3: Packet format__ + +## SAI Pipeline + +The packet processing pipeline is below: +![vlan_stack-pipeline](figures/vlan_stack/vlan_stack_pipeline.png "Figure 4: Vlan Stack SAI Pipeline") +__Figure 4: Vlan Stack SAI Pipeline__ + +## SAI Attribute + +| SAI Component | SAI attribute | Description | +| ------------- | ---------------------------------------------- | ------------------------------- | +| VLAN Stacking | SAI_VLAN_STACK_ATTR_STAGE | At which packet flow direction the action should take effect. Ingress or Egress | +| | SAI_VLAN_STACK_ATTR_ACTION | Include SWAP, PUSH and POP operation | +| | SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI | The "priority" of the new VLAN tag. Default value is 0xFF which will inherit the original vlan tag priority. | +| | SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_INNER | Used to match the processing packet inner dot1q header. | +| | SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_OUTER | Used to match the processing packet outer dot1q header. At least one of SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_INNER and SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_OUTER attribute should be set. The vlan stacking rule only take effect if packets' dot1q header VLAN_ID match this combination. | +| | SAI_VLAN_STACK_ATTR_PORT | Target port ID at which the vlan stacking will take effect | +| | SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_INNER | New inner vlan ID for the vlan stacking. If the ACTION is POP, this attribute will not take effect. | +| | SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_OUTER | New outer vlan ID for the vlan stacking. If the ACTION is POP, this attribute will not take effect. Else, one of SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_INNER and SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_OUTER attribute should be set | + + +## Use cases + +### Ingress/Add outer tag based on outer tag +Add an outer dot1q header with VID=100 for those packets with outer VID=10 at Ethernet10 + +#### Usage + +``` +sai_object_id_t vlan_stacking_oid; +sai_attribute_t attr; +vector vlan_stacking_entry_attrs; + +attr.id = SAI_VLAN_STACK_ATTR_STAGE; +attr.value.s32 = SAI_VLAN_STACK_STAGE_INGRESS; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ACTION; +attr.value.s32 = SAI_VLAN_STACK_ACTION_PUSH; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_OUTER; +attr.value.u16 = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_PORT; +attr.value.oid = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_OUTER; +attr.value.u16 = 100; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI; +attr.value.u8 = 0; +vlan_stacking_entry_attrs.push(attr); + +sai_vlan_stack_api->create_vlan_stack(&vlan_stacking_oid, gSwitchId, (uint32_t)vlan_stacking_entry_attrs.size(), vlan_stacking_entry_attrs.data()); +``` + +#### Behavior + +![vlan_stack-ingress-push-outer](figures/vlan_stack/ingress_push_outer.png "Table 1: Ingress Push") +__Table 1: Vlan Stack Ingress Push Outer__ + +### Ingress/Add outer tag based on inner tag +Add an outer dot1q header with VID=100 for those packets with inner dot1q VID=10 at Ethernet10 + +#### Usage + +``` +sai_object_id_t vlan_stacking_oid; +sai_attribute_t attr; +vector vlan_stacking_entry_attrs; + +attr.id = SAI_VLAN_STACK_ATTR_STAGE; +attr.value.s32 = SAI_VLAN_STACK_STAGE_INGRESS; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ACTION; +attr.value.s32 = SAI_VLAN_STACK_ACTION_PUSH; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_INNER; +attr.value.u16 = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_PORT; +attr.value.oid = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_OUTER; +attr.value.u16 = 100; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI; +attr.value.u8 = 0; +vlan_stacking_entry_attrs.push(attr); + +sai_vlan_stack_api->create_vlan_stack(&vlan_stacking_oid, gSwitchId, (uint32_t)vlan_stacking_entry_attrs.size(), vlan_stacking_entry_attrs.data()); +``` + +#### Behavior + +![vlan_stack-ingress-push-inner](figures/vlan_stack/ingress_push_inner.png "Table 2: Ingress Push") +__Table 2: Vlan Stack Ingress Push Inner__ + +### Egress/Remove outer tag based on outer tag +Remove outer dot1q header for those packets with original outer dot1q header VID=100 at Ethernet20 + +#### Usage + +``` +sai_object_id_t vlan_stacking_oid; +sai_attribute_t attr; +vector vlan_stacking_entry_attrs; + +attr.id = SAI_VLAN_STACK_ATTR_STAGE; +attr.value.s32 = SAI_VLAN_STACK_STAGE_EGRESS; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ACTION; +attr.value.s32 = SAI_VLAN_STACK_ACTION_POP; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_OUTER; +attr.value.u16 = 100; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_PORT; +attr.value.oid = 20; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI; +attr.value.u8 = 0; +vlan_stacking_entry_attrs.push(attr); + +sai_vlan_stack_api->create_vlan_stack(&vlan_stacking_oid, gSwitchId, (uint32_t)vlan_stacking_entry_attrs.size(), vlan_stacking_entry_attrs.data()); +``` + +#### Behavior + +![vlan_stack-egress-pop-outer](figures/vlan_stack/egress_pop_outer.png "Table 3: Egress Pop Outer") +__Table 3: Vlan Stack Egress Pop Outer__ + +### Ingress/Swap inner tag based on inner tag +Change inner dot1q header to VID=100 for those packets with original inner dot1q header VID=10 when they flow into Ethernet10 + +#### Usage + +``` +sai_object_id_t vlan_stacking_oid; +sai_attribute_t attr; +vector vlan_stacking_entry_attrs; + +attr.id = SAI_VLAN_STACK_ATTR_STAGE; +attr.value.s32 = SAI_VLAN_STACK_STAGE_INGRESS; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ACTION; +attr.value.s32 = SAI_VLAN_STACK_ACTION_SWAP; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_INNER; +attr.value.u16 = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_PORT; +attr.value.oid = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_INNER; +attr.value.u16 = 100; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI; +attr.value.u8 = 0; +vlan_stacking_entry_attrs.push(attr); + +sai_vlan_stack_api->create_vlan_stack(&vlan_stacking_oid, gSwitchId, (uint32_t)vlan_stacking_entry_attrs.size(), vlan_stacking_entry_attrs.data()); +``` + +#### Behavior + +![vlan_stack-ingress-swap-inner](figures/vlan_stack/ingress_swap_inner.png "Table 4: Ingress Swap Inner") +__Table 4: Vlan Stack Ingress Swap Inner__ + +### Ingress/Swap outer tag based on outer tag +Change outer dot1q header to VID=100 for those packets with original outer dot1q header VID=10 when they flow into Ethernet10 + +#### Usage + +``` +sai_object_id_t vlan_stacking_oid; +sai_attribute_t attr; +vector vlan_stacking_entry_attrs; + +attr.id = SAI_VLAN_STACK_ATTR_STAGE; +attr.value.s32 = SAI_VLAN_STACK_STAGE_INGRESS; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ACTION; +attr.value.s32 = SAI_VLAN_STACK_ACTION_SWAP; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_OUTER; +attr.value.u16 = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_PORT; +attr.value.oid = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_OUTER; +attr.value.u16 = 100; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI; +attr.value.u8 = 0; +vlan_stacking_entry_attrs.push(attr); + +sai_vlan_stack_api->create_vlan_stack(&vlan_stacking_oid, gSwitchId, (uint32_t)vlan_stacking_entry_attrs.size(), vlan_stacking_entry_attrs.data()); +``` + +#### Behavior + +![vlan_stack-ingress-swap-outer](figures/vlan_stack/ingress_swap_outer.png "Table 5: Ingress Swap Outer") +__Table 5: Vlan Stack Ingress Swap Outer__ + +### Egress/Swap inner tag based on inner tag +Change inner dot1q header to VID=10 for those packets with original inner dot1q header VID=100 when they flow away from Ethernet20 + +#### Usage + +``` +sai_object_id_t vlan_stacking_oid; +sai_attribute_t attr; +vector vlan_stacking_entry_attrs; + +attr.id = SAI_VLAN_STACK_ATTR_STAGE; +attr.value.s32 = SAI_VLAN_STACK_STAGE_EGRESS; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ACTION; +attr.value.s32 = SAI_VLAN_STACK_ACTION_SWAP; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_INNER; +attr.value.u16 = 100; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_PORT; +attr.value.oid = 20; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_INNER; +attr.value.u16 = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI; +attr.value.u8 = 0; +vlan_stacking_entry_attrs.push(attr); + +sai_vlan_stack_api->create_vlan_stack(&vlan_stacking_oid, gSwitchId, (uint32_t)vlan_stacking_entry_attrs.size(), vlan_stacking_entry_attrs.data()); +``` + +#### Behavior + +![vlan_stack-egress-swap-inner](figures/vlan_stack/egress_swap_inner.png "Table 6: Egress Swap Inner") +__Table 6: Vlan Stack Egress Swap Inner__ + +### Egress/Swap outer tag based on outer tag +Change outer dot1q header to VID=10 for those packets with original outer dot1q header VID=100 when they flow away from Ethernet20 + +#### Usage + +``` +sai_object_id_t vlan_stacking_oid; +sai_attribute_t attr; +vector vlan_stacking_entry_attrs; + +attr.id = SAI_VLAN_STACK_ATTR_STAGE; +attr.value.s32 = SAI_VLAN_STACK_STAGE_EGRESS; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ACTION; +attr.value.s32 = SAI_VLAN_STACK_ACTION_SWAP; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_OUTER; +attr.value.u16 = 100; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_PORT; +attr.value.oid = 20; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_OUTER; +attr.value.u16 = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI; +attr.value.u8 = 0; +vlan_stacking_entry_attrs.push(attr); + +sai_vlan_stack_api->create_vlan_stack(&vlan_stacking_oid, gSwitchId, (uint32_t)vlan_stacking_entry_attrs.size(), vlan_stacking_entry_attrs.data()); +``` + +#### Behavior + +![vlan_stack-egress-swap-outer](figures/vlan_stack/egress_swap_outer.png "Table 7: Egress Swap Outer") +__Table 7: Vlan Stack Egress Swap Outer__ + +### Ingress/Swap on double tag from single tag +Change the incoming packet with outer dot1q header VID=200 to a double tag packet with outer VID=100 and inner VID=10 at port Ethernet10 + +#### Usage + +``` +sai_object_id_t vlan_stacking_oid; +sai_attribute_t attr; +vector vlan_stacking_entry_attrs; + +attr.id = SAI_VLAN_STACK_ATTR_STAGE; +attr.value.s32 = SAI_VLAN_STACK_STAGE_INGRESS; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ACTION; +attr.value.s32 = SAI_VLAN_STACK_ACTION_SWAP; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_OUTER; +attr.value.u16 = 200; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_PORT; +attr.value.oid = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_INNER; +attr.value.u16 = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_OUTER; +attr.value.u16 = 100; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI; +attr.value.u8 = 0; +vlan_stacking_entry_attrs.push(attr); + +sai_vlan_stack_api->create_vlan_stack(&vlan_stacking_oid, gSwitchId, (uint32_t)vlan_stacking_entry_attrs.size(), vlan_stacking_entry_attrs.data()); +``` + +#### Behavior + +![vlan_stack-ingress-swap-single-double](figures/vlan_stack/ingress_swap_single_double.png "Table 8: Ingress Swap Single Double") +__Table 8: Vlan Stack Ingress Swap Single to Double__ + +### Egress/Swap on single tag from double tag +Change the outgoing double tag packet with outer VID=100 and inner VID=10 to a single tag packet with VID=200 at port Ethernet20 + +#### Usage + +``` +sai_object_id_t vlan_stacking_oid; +sai_attribute_t attr; +vector vlan_stacking_entry_attrs; + +attr.id = SAI_VLAN_STACK_ATTR_STAGE; +attr.value.s32 = SAI_VLAN_STACK_STAGE_EGRESS; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ACTION; +attr.value.s32 = SAI_VLAN_STACK_ACTION_SWAP; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_INNER; +attr.value.u16 = 10; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_OUTER; +attr.value.u16 = 100; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_PORT; +attr.value.oid = 20; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_OUTER; +attr.value.u16 = 200; +vlan_stacking_entry_attrs.push(attr); + +attr.id = SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI; +attr.value.u8 = 0; +vlan_stacking_entry_attrs.push(attr); + +sai_vlan_stack_api->create_vlan_stack(&vlan_stacking_oid, gSwitchId, (uint32_t)vlan_stacking_entry_attrs.size(), vlan_stacking_entry_attrs.data()); +``` + +#### Behavior + +![vlan_stack-egress-swap-double-single](figures/vlan_stack/egress_swap_double_single.png "Table 9: Egress Swap Double Single") +__Table 9: Vlan Stack Ingress Swap Double to Single__ \ No newline at end of file diff --git a/doc/behavioral model/pipeline_v9_vlan_stack.pdf b/doc/behavioral model/pipeline_v9_vlan_stack.pdf new file mode 100644 index 000000000..8047d882c Binary files /dev/null and b/doc/behavioral model/pipeline_v9_vlan_stack.pdf differ diff --git a/doc/figures/vlan_stack/TCPIP_802.1ad_DoubleTag.png b/doc/figures/vlan_stack/TCPIP_802.1ad_DoubleTag.png new file mode 100644 index 000000000..438bc452c Binary files /dev/null and b/doc/figures/vlan_stack/TCPIP_802.1ad_DoubleTag.png differ diff --git a/doc/figures/vlan_stack/egress_pop_outer.png b/doc/figures/vlan_stack/egress_pop_outer.png new file mode 100644 index 000000000..3c65bf168 Binary files /dev/null and b/doc/figures/vlan_stack/egress_pop_outer.png differ diff --git a/doc/figures/vlan_stack/egress_swap_double_single.png b/doc/figures/vlan_stack/egress_swap_double_single.png new file mode 100644 index 000000000..06f9b8f0d Binary files /dev/null and b/doc/figures/vlan_stack/egress_swap_double_single.png differ diff --git a/doc/figures/vlan_stack/egress_swap_inner.png b/doc/figures/vlan_stack/egress_swap_inner.png new file mode 100644 index 000000000..b8484e772 Binary files /dev/null and b/doc/figures/vlan_stack/egress_swap_inner.png differ diff --git a/doc/figures/vlan_stack/egress_swap_outer.png b/doc/figures/vlan_stack/egress_swap_outer.png new file mode 100644 index 000000000..cead92617 Binary files /dev/null and b/doc/figures/vlan_stack/egress_swap_outer.png differ diff --git a/doc/figures/vlan_stack/ingress_push_inner.png b/doc/figures/vlan_stack/ingress_push_inner.png new file mode 100644 index 000000000..877c16630 Binary files /dev/null and b/doc/figures/vlan_stack/ingress_push_inner.png differ diff --git a/doc/figures/vlan_stack/ingress_push_outer.png b/doc/figures/vlan_stack/ingress_push_outer.png new file mode 100644 index 000000000..b9827c21e Binary files /dev/null and b/doc/figures/vlan_stack/ingress_push_outer.png differ diff --git a/doc/figures/vlan_stack/ingress_swap_inner.png b/doc/figures/vlan_stack/ingress_swap_inner.png new file mode 100644 index 000000000..16f0ace4f Binary files /dev/null and b/doc/figures/vlan_stack/ingress_swap_inner.png differ diff --git a/doc/figures/vlan_stack/ingress_swap_outer.png b/doc/figures/vlan_stack/ingress_swap_outer.png new file mode 100644 index 000000000..e0ae26b1a Binary files /dev/null and b/doc/figures/vlan_stack/ingress_swap_outer.png differ diff --git a/doc/figures/vlan_stack/ingress_swap_single_double.png b/doc/figures/vlan_stack/ingress_swap_single_double.png new file mode 100644 index 000000000..f3837d8f5 Binary files /dev/null and b/doc/figures/vlan_stack/ingress_swap_single_double.png differ diff --git a/doc/figures/vlan_stack/vlan_stack_QinQ_usecase.png b/doc/figures/vlan_stack/vlan_stack_QinQ_usecase.png new file mode 100644 index 000000000..266bb4529 Binary files /dev/null and b/doc/figures/vlan_stack/vlan_stack_QinQ_usecase.png differ diff --git a/doc/figures/vlan_stack/vlan_stack_pipeline.png b/doc/figures/vlan_stack/vlan_stack_pipeline.png new file mode 100644 index 000000000..267d37cc3 Binary files /dev/null and b/doc/figures/vlan_stack/vlan_stack_pipeline.png differ diff --git a/doc/figures/vlan_stack/vlan_stack_vlan_xlate_usecase.png b/doc/figures/vlan_stack/vlan_stack_vlan_xlate_usecase.png new file mode 100644 index 000000000..24234b8a9 Binary files /dev/null and b/doc/figures/vlan_stack/vlan_stack_vlan_xlate_usecase.png differ diff --git a/inc/sai.h b/inc/sai.h index 85ffc5ce2..1aa0a286f 100644 --- a/inc/sai.h +++ b/inc/sai.h @@ -69,6 +69,7 @@ #include "saiudf.h" #include "saivirtualrouter.h" #include "saivlan.h" +#include "saivlanstack.h" #include "saiwred.h" #include "saidtel.h" #include "saibfd.h" @@ -144,6 +145,7 @@ typedef enum _sai_api_t SAI_API_GENERIC_PROGRAMMABLE = 47, /** + +/** + * @defgroup SAIVLANSTACK SAI - VLAN STACK specific API definitions + * + * @{ + */ + +/** + * @brief VLAN Stack stage + */ +typedef enum _sai_vlan_stack_stage_t +{ + SAI_VLAN_STACK_STAGE_INGRESS, + + SAI_VLAN_STACK_STAGE_EGRESS, + +} sai_vlan_stack_stage_t; + +/** + * @brief VLAN Stack action + * + * If the action is SAI_VLAN_STACK_ACTION_SWAP, the original vlan id of the frame will be replaced + * with new vlan id and the new vlan id will be placed in the original tag position. + * If the action is SAI_VLAN_STACK_ACTION_PUSH, the original vlan id of the frame will be kept if + * exists and the new vlan id will be added as the outer vlan tag. + * If the action is SAI_VLAN_STACK_ACTION_POP, the original vlan id of the frame will be removed + * if exists. + */ +typedef enum _sai_vlan_stack_action_t +{ + SAI_VLAN_STACK_ACTION_SWAP, + + SAI_VLAN_STACK_ACTION_PUSH, + + SAI_VLAN_STACK_ACTION_POP, + +} sai_vlan_stack_action_t; + +/** + * @brief Attributes for VLAN Stack + */ +typedef enum _sai_vlan_stack_attr_t +{ + /** + * @brief Start of attributes + */ + SAI_VLAN_STACK_ATTR_START, + + /** + * @brief Stage type + * If action type is PUSH, this should set to INGRESS + * If action type is POP, this should set to EGRESS + * + * @type sai_vlan_stack_stage_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + */ + SAI_VLAN_STACK_ATTR_STAGE = SAI_VLAN_STACK_ATTR_START, + + /** + * @brief Action type + * + * @type sai_vlan_stack_action_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + */ + SAI_VLAN_STACK_ATTR_ACTION, + + /** + * @brief Original Vlan ID of the inner + * + * @type sai_uint16_t + * @flags CREATE_AND_SET + * @isvlan true + * @default 0 + */ + SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_INNER, + + /** + * @brief Original Vlan ID of the outer + * + * @type sai_uint16_t + * @flags CREATE_AND_SET + * @isvlan true + * @default 0 + */ + SAI_VLAN_STACK_ATTR_ORIGINAL_VLAN_ID_OUTER, + + /** + * @brief VLAN Stack port object + * + * @type sai_object_id_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + * @objects SAI_OBJECT_TYPE_PORT, SAI_OBJECT_TYPE_LAG + */ + SAI_VLAN_STACK_ATTR_PORT, + + /** + * @brief Applied Vlan ID of the inner + * If action type is POP, should not set this attribute + * + * @type sai_uint16_t + * @flags CREATE_AND_SET + * @isvlan true + * @default 0 + * @validonly SAI_VLAN_STACK_ATTR_ACTION == SAI_VLAN_STACK_ACTION_PUSH or SAI_VLAN_STACK_ATTR_ACTION == SAI_VLAN_STACK_ACTION_SWAP + */ + SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_INNER, + + /** + * @brief Applied Vlan ID of the outer + * If action type is POP, should not set this attribute + * + * @type sai_uint16_t + * @flags CREATE_AND_SET + * @isvlan true + * @default 0 + * @validonly SAI_VLAN_STACK_ATTR_ACTION == SAI_VLAN_STACK_ACTION_PUSH or SAI_VLAN_STACK_ATTR_ACTION == SAI_VLAN_STACK_ACTION_SWAP + */ + SAI_VLAN_STACK_ATTR_APPLIED_VLAN_ID_OUTER, + + /** + * @brief The packet priority (3 bits) in the vlan tag + * Range from 0 to 7, priority from low to high. + * Default 0xFF will inherit the original vlan tag priority + * + * @type sai_uint8_t + * @flags CREATE_AND_SET + * @default 0xFF + */ + SAI_VLAN_STACK_ATTR_VLAN_APPLIED_PRI, + + /** + * @brief End of attributes + */ + SAI_VLAN_STACK_ATTR_END, + + /** Custom range base value */ + SAI_VLAN_STACK_ATTR_CUSTOM_RANGE_START = 0x10000000, + + /** End of custom range base */ + SAI_VLAN_STACK_ATTR_CUSTOM_RANGE_END + +} sai_vlan_stack_attr_t; + +/** + * @brief Create and apply a single VLAN Stack rule + * + * @param[out] vlan_stack_id VLAN Stack ID + * @param[in] switch_id Switch id + * @param[in] attr_count Number of attributes + * @param[in] attr_list Array of attributes + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_create_vlan_stack_fn)( + _Out_ sai_object_id_t *vlan_stack_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + +/** + * @brief Remove a VLAN Stack rule + * + * @param[in] vlan_stack_id VLAN Stack ID + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_remove_vlan_stack_fn)( + _In_ sai_object_id_t vlan_stack_id); + +/** + * @brief Modify VLAN Stack rule attribute + * + * @param[in] vlan_stack_id VLAN Stack ID + * @param[in] attr Attribute + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_set_vlan_stack_attribute_fn)( + _In_ sai_object_id_t vlan_stack_id, + _In_ const sai_attribute_t *attr); + +/** + * @brief Get VLAN Stack rule attribute + * + * @param[in] vlan_stack_id VLAN Stack ID + * @param[in] attr_count Number of attributes + * @param[inout] attr_list Array of attributes + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_get_vlan_stack_attribute_fn)( + _In_ sai_object_id_t vlan_stack_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list); + +/** + * @brief VLAN STACK methods table retrieved with sai_api_query() + */ +typedef struct _sai_vlan_stack_api_t +{ + sai_create_vlan_stack_fn create_vlan_stack; + sai_remove_vlan_stack_fn remove_vlan_stack; + sai_set_vlan_stack_attribute_fn set_vlan_stack_attribute; + sai_get_vlan_stack_attribute_fn get_vlan_stack_attribute; +} sai_vlan_stack_api_t; + +/** + * @} + */ +#endif /** __SAIVLANSTACK_H_ */ diff --git a/meta/saisanitycheck.c b/meta/saisanitycheck.c index 0a4a8cce2..3c242d8a5 100644 --- a/meta/saisanitycheck.c +++ b/meta/saisanitycheck.c @@ -4784,7 +4784,8 @@ void check_object_ro_list( oi->objecttype == SAI_OBJECT_TYPE_DTEL || oi->objecttype == SAI_OBJECT_TYPE_DTEL_QUEUE_REPORT || oi->objecttype == SAI_OBJECT_TYPE_DTEL_EVENT || - oi->objecttype == SAI_OBJECT_TYPE_GENERIC_PROGRAMMABLE) + oi->objecttype == SAI_OBJECT_TYPE_GENERIC_PROGRAMMABLE || + oi->objecttype == SAI_OBJECT_TYPE_VLAN_STACK) { /* * We skip hostif table entry since there is no 1 object which can